「luogu3313」[SDOI2014]旅行
树链剖分,每种颜色开一个线段树维护,动态开点。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=100010; 4 int n,q,w[N],c[N],maxc=100000; 5 vector<int>g[N]; 6 inline int read(){ 7 int x=0,w=1;char c=0; 8 while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();} 9 while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar(); 10 return x*w; 11 } 12 int fa[N],son[N],dep[N],siz[N],top[N],id[N],totid; 13 void dfs1(int k,int father,int d){ 14 int x; 15 fa[k]=father,dep[k]=d,siz[k]=1; 16 for(int i=0;i<g[k].size();i++){ 17 x=g[k][i]; 18 if(x==father) continue; 19 dfs1(x,k,d+1); 20 siz[k]+=siz[x]; 21 if(siz[x]>siz[son[k]]) son[k]=x; 22 } 23 return; 24 } 25 void dfs2(int k,int tp){ 26 int x; 27 top[k]=tp,id[k]=++totid; 28 if(son[k]) dfs2(son[k],tp); 29 for(int i=0;i<g[k].size();i++){ 30 x=g[k][i]; 31 if(x==fa[k]||x==son[k]) continue; 32 dfs2(x,x); 33 } 34 return; 35 } 36 int root[N],lc[N<<6],rc[N<<6],mx[N<<6],sum[N<<6],tot; 37 struct Segtree{ 38 inline void pushup(int k){ 39 sum[k]=sum[lc[k]]+sum[rc[k]]; 40 mx[k]=max(mx[lc[k]],mx[rc[k]]); 41 return; 42 } 43 int quemx(int k,int l,int r,int ql,int qr){ 44 if(!k) return 0; 45 if(l==ql&&r==qr) return mx[k]; 46 int mid=(l+r)>>1; 47 if(qr<=mid) return quemx(lc[k],l,mid,ql,qr); 48 else if(ql>mid) return quemx(rc[k],mid+1,r,ql,qr); 49 else return max(quemx(lc[k],l,mid,ql,mid),quemx(rc[k],mid+1,r,mid+1,qr)); 50 } 51 int quesum(int k,int l,int r,int ql,int qr){ 52 if(!k) return 0; 53 if(l==ql&&r==qr) return sum[k]; 54 int mid=(l+r)>>1; 55 if(qr<=mid) return quesum(lc[k],l,mid,ql,qr); 56 else if(ql>mid) return quesum(rc[k],mid+1,r,ql,qr); 57 else return quesum(lc[k],l,mid,ql,mid)+quesum(rc[k],mid+1,r,mid+1,qr); 58 } 59 void modify(int& k,int l,int r,int pos,int x){ 60 if(!k) k=++tot; 61 if(l==r){sum[k]=x,mx[k]=x;return;} 62 int mid=(l+r)>>1; 63 if(pos<=mid) modify(lc[k],l,mid,pos,x); 64 else modify(rc[k],mid+1,r,pos,x); 65 pushup(k); 66 return; 67 } 68 }segtree; 69 inline int optquesum(int s,int t,int color){ 70 int ans=0; 71 while(top[s]!=top[t]){ 72 if(dep[top[s]]<dep[top[t]]) swap(s,t); 73 ans+=segtree.quesum(root[color],1,maxc,id[top[s]],id[s]); 74 s=fa[top[s]]; 75 } 76 // if(s==t) return ans; 77 if(dep[s]<dep[t]) swap(s,t); 78 ans+=segtree.quesum(root[color],1,maxc,id[t],id[s]); 79 return ans; 80 } 81 inline int optquemx(int s,int t,int color){ 82 int ans=0; 83 while(top[s]!=top[t]){ 84 if(dep[top[s]]<dep[top[t]]) swap(s,t); 85 ans=max(ans,segtree.quemx(root[color],1,maxc,id[top[s]],id[s])); 86 s=fa[top[s]]; 87 } 88 // if(s==t) return ans; 89 if(dep[s]<dep[t]) swap(s,t); 90 ans=max(ans,segtree.quemx(root[color],1,maxc,id[t],id[s])); 91 return ans; 92 } 93 int main(){ 94 int t1,t2; 95 char opt[10]; 96 n=read(),q=read(); 97 for(int i=1;i<=n;i++) w[i]=read(),c[i]=read(); 98 for(int i=1;i<n;i++){ 99 t1=read(),t2=read(); 100 g[t1].push_back(t2);g[t2].push_back(t1); 101 } 102 dfs1(1,0,1);dfs2(1,1); 103 for(int i=1;i<=n;i++) segtree.modify(root[c[i]],1,maxc,id[i],w[i]); 104 while(q--){ 105 scanf("%s",opt); 106 t1=read(),t2=read(); 107 if(opt[1]=='C'){ 108 segtree.modify(root[c[t1]],1,maxc,id[t1],0); 109 c[t1]=t2; 110 segtree.modify(root[t2],1,maxc,id[t1],w[t1]); 111 }else if(opt[1]=='W'){ 112 w[t1]=t2; 113 segtree.modify(root[c[t1]],1,maxc,id[t1],t2); 114 } 115 else if(opt[1]=='S') printf("%d\n",optquesum(t1,t2,c[t2])); 116 else printf("%d\n",optquemx(t1,t2,c[t2])); 117 } 118 return 0; 119 }