1. 程式人生 > >【NOI省選模擬】小奇的花園

【NOI省選模擬】小奇的花園

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<map>
  7 
  8 #define For(i,a,b)for(register int i=a;i<=b;++i)
  9 #define Dwn(i,a,b)for(register int i=a;i>=b;--i)
 10 #define
Re register 11 #define Pn putchar('\n') 12 13 using namespace std; 14 15 const int N=1e5+5,Nr=1e7+5; 16 int head[N],nxt[N*2],v[N*2],cnt=1; 17 int f[N][21],dfx[N],dID=0,dep[N],sz[N]; 18 int rt[N*3],ls[Nr],rs[Nr],tag[Nr],tr[Nr],tID=0; 19 int n,m,x,y,T[N*3],cID=0,t,Q,ans=0; 20 map<int
,int>mp; 21 inline void read(int &v){ 22 v=0; 23 char c=getchar(); 24 while(c<'0'||c>'9')c=getchar(); 25 while(c>='0'&&c<='9')v=v*10+c-'0',c=getchar(); 26 } 27 void write(int x){ 28 if(x>9)write(x/10); 29 int xx=x%10; 30 putchar(xx+'
0'); 31 } 32 void add(int ux,int vx){ 33 cnt++; 34 nxt[cnt]=head[ux]; head[ux]=cnt; v[cnt]=vx; 35 cnt++; 36 nxt[cnt]=head[vx]; head[vx]=cnt; v[cnt]=ux; 37 } 38 39 void DFS(int x,int fa){ 40 sz[x]=1; 41 dfx[x]=++dID; 42 for(Re int i=head[x];i;i=nxt[i]){ 43 int vv=v[i]; 44 if(vv==fa)continue; 45 dep[vv]=dep[x]+1; 46 f[vv][0]=x; 47 DFS(vv,x); 48 sz[x]+=sz[vv]; 49 } 50 } 51 52 int LCA(int x,int y){ 53 if(dep[x]<dep[y])swap(x,y); 54 Dwn(b,20,0)if(f[x][b]!=-1){ 55 if(dep[f[x][b]]>=dep[y])x=f[x][b]; 56 } 57 if(x==y)return x; 58 Dwn(b,20,0)if(f[x][b]!=-1&&f[y][b]!=-1&&f[x][b]!=f[y][b]){ 59 x=f[x][b]; y=f[y][b]; 60 } 61 return f[x][0]; 62 } 63 64 65 void pDown(int o,int l,int r){ 66 if(!tag[o]||l==r)return; 67 int tg=tag[o]; tag[o]=0; 68 if(!ls[o])ls[o]=++tID; 69 if(!rs[o])rs[o]=++tID; 70 tr[ls[o]]+=tg; tag[ls[o]]+=tg; 71 tr[rs[o]]+=tg; tag[rs[o]]+=tg; 72 } 73 74 void Ins(int &o,int l,int r,int lx,int rx,int dt){ 75 if(!o)o=++tID; 76 if(lx<=l&&rx>=r){ 77 tr[o]+=dt; tag[o]+=dt; 78 return; 79 } 80 pDown(o,l,r); 81 int m=(l+r)>>1; 82 if(lx<=m)Ins(ls[o],l,m,lx,rx,dt); 83 if(rx>m)Ins(rs[o],m+1,r,lx,rx,dt); 84 } 85 86 int Qry(int o,int l,int r,int px){ 87 if(!o)return 0; 88 if(l==r)return tr[o]; 89 pDown(o,l,r); 90 int m=(l+r)>>1; 91 if(px<=m)return Qry(ls[o],l,m,px); 92 else return Qry(rs[o],m+1,r,px); 93 } 94 95 96 int main(){ 97 freopen("garden.in","r",stdin); 98 freopen("garden.out","w",stdout); 99 read(n); read(Q); 100 For(i,1,n){ 101 read(t); 102 if(!mp[t])mp[t]=++cID; 103 T[i]=mp[t]; 104 } 105 For(i,1,n-1){ 106 read(x); read(y); 107 add(x,y); 108 } 109 110 memset(f,-1,sizeof(f)); 111 DFS(1,0); 112 For(b,1,20) For(i,1,n){ 113 if(f[i][b-1]==-1)continue; 114 f[i][b]=f[ f[i][b-1] ][b-1]; 115 } 116 117 For(i,1,n){ 118 int lx=dfx[i]; 119 int rx=dfx[i]+sz[i]-1; 120 Ins(rt[T[i]],1,n,lx,rx,1); 121 } 122 123 For(i,1,Q){ 124 125 char opt=getchar(); 126 while(opt!='C'&&opt!='Q')opt=getchar(); 127 if(opt=='C'){ 128 read(x); read(t); 129 x^=ans; t^=ans; 130 if(!mp[t])mp[t]=++cID; 131 t=mp[t]; 132 int lx=dfx[x],rx=dfx[x]+sz[x]-1; 133 134 Ins(rt[T[x]],1,n,lx,rx,-1); 135 Ins(rt[t],1,n,lx,rx,1); 136 T[x]=t; 137 } 138 if(opt=='Q'){ 139 read(x); read(y); read(t); 140 x^=ans; y^=ans; t^=ans; 141 if(!mp[t])mp[t]=++cID; 142 t=mp[t]; 143 int xy=LCA(x,y); 144 int fn; 145 fn=Qry(rt[t],1,n,dfx[x])+Qry(rt[t],1,n,dfx[y]); 146 fn-=Qry(rt[t],1,n,dfx[xy])*2; 147 if(T[xy]==t)fn++; 148 ans=fn; 149 write(fn); Pn; 150 } 151 } 152 fclose(stdin); fclose(stdout); 153 return 0; 154 }