「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
",optquesum(t1,t2,c[t2]));
116         else printf("%d
",optquemx(t1,t2,c[t2]));
117     }
118     return 0;
119 }
原文地址:https://www.cnblogs.com/mycups/p/8547673.html