记录编号 371495 评测结果 AAAAAAAAAA
题目名称 [HZOI 2015]黑树白 最终得分 100
用户昵称 Gravatar哒哒哒哒哒! 是否通过 通过
代码语言 C++ 运行时间 3.978 s
提交时间 2017-02-16 10:57:39 内存使用 234.06 MiB
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define ll long long 
int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
	return x*f;
}
const int maxn=80100;
struct edge{int to,next;}e[maxn*2];
int tot,head[maxn];
void add(int u,int v){
	e[++tot]=(edge){v,head[u]};head[u]=tot;
}

int n,m,c[maxn],ans,cnt,le,ri;
int sta[maxn],end[maxn],dfn;
int size[maxn],deep[maxn],fa[maxn];
int son[maxn],top[maxn];

void dfs(int u){
	sta[u]=++dfn;size[u]=1;
	for(int i=head[u];i;i=e[i].next){
		int to=e[i].to;
		if(size[to])continue;
		fa[to]=u,deep[to]=deep[u]+1;
		dfs(to);size[u]+=size[to];
		if(size[to]>size[son[u]])son[u]=to;
	}
	end[u]=dfn;
}
void dfs(int u,int tp){
	top[u]=tp;
	if(son[u])dfs(son[u],tp);
	for(int i=head[u];i;i=e[i].next)
		if(!top[e[i].to])dfs(e[i].to,e[i].to);
}
int lca(int a,int b){
	while(top[a]!=top[b]){
		if(deep[top[a]]<deep[top[b]])swap(a,b);
		a=fa[top[a]];
	}return deep[a]<deep[b]?a:b;
}

int lc[maxn*250],rc[maxn*250],sum[maxn*250];
int root[maxn],tree[maxn];
void insert(int l,int r,int pr,int &rt,int p,int x){
	sum[rt=++cnt]=sum[pr]+x;
	if(l==r) return;int mid=(l+r)/2;
	lc[rt]=lc[pr],rc[rt]=rc[pr];
	if(p<=mid) insert(l,mid,lc[pr],lc[rt],p,x);
	else insert(mid+1,r,rc[pr],rc[rt],p,x);
}
void Build(int u,int Fa){
	insert(1,n,root[Fa],root[u],c[u],1);
	for(int i=head[u];i;i=e[i].next)
		if(e[i].to!=Fa) Build(e[i].to,u);
}
void add(int x,int y,int ad){
	if(!x)return;
	for(int i=x;i<=n;i+=i&-i)
		insert(1,n,tree[i],tree[i],y,ad);
}
int query(int l,int r,int rt){
	if(!rt) return 0;
	if(le<=l&&ri>=r) return sum[rt];
	int mid=(l+r)/2,res=0;
	if(le<=mid) res+=query(l,mid,lc[rt]);
	if(ri>mid) res+=query(mid+1,r,rc[rt]);
	return res;
}
int Add(int x){
	if(!x) return 0;
	ll res=query(1,n,root[x]);
	for(int i=sta[x];i;i-=i&-i)res+=query(1,n,tree[i]);
	return res;
}
int Sub(int x){
	if(!x) return 0;
	ll res=query(1,n,root[x]);
	for(int i=sta[x];i;i-=i&-i)res+=query(1,n,tree[i]);
	return res;
}
int main(){
	freopen("D_Tree.in","r",stdin);freopen("D_Tree.out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=n;i++) c[i]=read();
	for(int i=1;i<n;i++){
		int a=read(),b=read();
		add(a,b);add(b,a);
	}
	dfs(1);dfs(1,1);Build(1,0);
	char op[5];
	while(m--){
		scanf("%s",op);
		int u=(read()+ans)%n+1,v=(read()+ans)%n+1;
		if(op[0]=='M'){
			add(sta[u],c[u],-1);add(end[u]+1,c[u],1);
			c[u]=v;
			add(sta[u],c[u],1);add(end[u]+1,c[u],-1);
		}else{
			int lc=lca(u,v);le=read(),ri=read();
			ans=Add(u)+Add(v)-Sub(lc)-Sub(fa[lc]);
			printf("%d\n",ans);
		}
	}
	fclose(stdin);fclose(stdout);
	return 0;
}