记录编号 299825 评测结果 WAAAAAWWWWWWWWWWWWWW
题目名称 [HZOI 2015] 可持久化动态树(题目有误) 最终得分 25
用户昵称 GravatarTenderRun 是否通过 未通过
代码语言 C++ 运行时间 7.077 s
提交时间 2016-08-27 14:36:16 内存使用 490.86 MiB
显示代码纯文本
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=100010,M=30000010,mod=1<<14;
int n,Q,cnt,fir[N],nxt[N*2],to[N*2];
int sz[N],son[N],fa[N],dep[N],nrt;
int top[N],id[N],ed[N],tot;
int rt[N],ch[M][2],sum[M],add[M],len[M];
void addedge(int a,int b){
	nxt[++cnt]=fir[a];to[fir[a]=cnt]=b;
	nxt[++cnt]=fir[b];to[fir[b]=cnt]=a;
}

void DFS(int x){
	sz[x]=1;
	for(int i=fir[x];i;i=nxt[i])
		if(to[i]!=fa[x]){
			fa[to[i]]=x;dep[to[i]]=dep[x]+1;
			DFS(to[i]);sz[x]+=sz[to[i]];
			if(sz[son[x]]<sz[to[i]])
				son[x]=to[i];
		}
}

void DFS(int x,int tp){
	id[x]=++tot;top[x]=tp;
	if(son[x])DFS(son[x],tp);
	for(int i=fir[x];i;i=nxt[i])
		if(to[i]!=fa[x]&&to[i]!=son[x])
			DFS(to[i],to[i]);
	ed[x]=tot;		
}
#define ls ch[x][0]
#define rs ch[x][1]
#define lps ch[pre][0]
#define rps ch[pre][1]
#define mid ((l+r)>>1)
int Newnode(int l,int p=0){
	len[++tot]=l;
	if(p){
		ch[tot][0]=ch[p][0];
		ch[tot][1]=ch[p][1];
		sum[tot]=sum[p];
		add[tot]=add[p];
	}
	return tot;
}
void Push_up(int x){sum[x]=(sum[ls]+sum[rs])%mod;}
void Add(int x,int k){(sum[x]+=len[x]*k%mod)%=mod;(add[x]+=k)%=mod;}
void Push_down(int x,int l,int r){ 
	if(add[x]){
		ls=Newnode(mid-l+1,ls);
		rs=Newnode(r-mid,rs);
		Add(ls,add[x]);
		Add(rs,add[x]);
		add[x]=0;
	}
}

int Query(int x,int l,int r,int a,int b){
	if(!x||l>=a&&r<=b)return sum[x];
	int ret=0;Push_down(x,l,r);
	if(mid>=a)ret=Query(ls,l,mid,a,b);
	if(mid<b)ret+=Query(rs,mid+1,r,a,b);
	return ret;
}

int Solve(int x,int y){
	int ret=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		(ret+=Query(nrt,1,n,id[top[x]],id[x]))%=mod;
		x=fa[top[x]];	
	}
	if(dep[x]<dep[y])swap(x,y);
	(ret+=Query(nrt,1,n,id[y],id[x]))%=mod;
	return ret%mod;
}

void Clr(int pre,int &x,int l,int r,int a,int b){
	Push_down(pre,l,r);
	x=Newnode(r-l+1,pre);
	if(l>=a&&r<=b){x=0;return;}
	if(mid>=a)Clr(lps,ls,l,mid,a,b);
	if(mid<b)Clr(rps,rs,mid+1,r,a,b);
	Push_up(x);
}

void Clear(int x,int y){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		Clr(nrt,nrt,1,n,id[top[x]],id[x]);x=fa[top[x]];	
	}
	if(dep[x]<dep[y])swap(x,y);
	Clr(nrt,nrt,1,n,id[y],id[x]);
}

void Update(int pre,int &x,int l,int r,int a,int b,int k){
	Push_down(pre,l,r);
	x=Newnode(r-l+1,pre);
	if(l>=a&&r<=b){Add(x,k);return;}
	if(mid>=a)Update(lps,ls,l,mid,a,b,k);
	if(mid<b)Update(rps,rs,mid+1,r,a,b,k);
	Push_up(x);
}

void Modify(int x,int y,int k){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		Update(nrt,nrt,1,n,id[top[x]],id[x],k);
		x=fa[top[x]];	
	}
	if(dep[x]<dep[y])swap(x,y);
	Update(nrt,nrt,1,n,id[y],id[x],k);
}

int a,b,k;
char op[5];
int main(){
	freopen("great_tree.in","r",stdin);
	freopen("great_tree.out","w",stdout);
	scanf("%d%d",&n,&Q);
	for(int i=1;i<n;i++){
		scanf("%d%d",&a,&b);
		addedge(a,b);
	}	
	DFS(1);DFS(1,1);tot=0;
	for(int t=1;t<=Q;t++){
		scanf("%s",op);
		if(op[0]=='B'){
			scanf("%d%d",&a,&k);
			Update(nrt,nrt,1,n,id[a],ed[a],k%mod);
		}
		else if(op[0]=='C'){
			scanf("%d%d%d",&a,&b,&k);
			Modify(a,b,k%mod);
		}
		else if(op[0]=='Q'){
			scanf("%d%d",&a,&b);
			printf("%d\n",Solve(a,b));
		}
		else if(op[0]=='E'){
			scanf("%d%d",&a,&b);
			Clear(a,b);
		}
		else{
			scanf("%d",&k);
			nrt=rt[k];
		}
		rt[t]=nrt;
	}
	return 0;
}