bzoj 3531 旅行
题目大意:
一棵树,每个点有颜色
支持四种操作: 单点改颜色/权值 查询两点间路径上与起点或终点的颜色一样的点的权值和/最大值
思路:
动态开点 树链剖分
重点在动态开点
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstdlib> 6 #include<cstring> 7 #include<queue> 8 #include<map> 9 #include<vector> 10 #define ll long long 11 #define inf 2139062143 12 #define MAXN 100100 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 int n,q,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt,val[MAXN],c[MAXN]; 22 int bl[MAXN],hsh[MAXN],fa[MAXN],dep[MAXN],sz[MAXN]; 23 int s[MAXN<<8][2],mx[MAXN<<8],sum[MAXN<<8],rt[MAXN],tot; 24 char ch[10]; 25 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;} 26 void dfs(int x) 27 { 28 sz[x]=1; 29 for(int i=fst[x];i;i=nxt[i]) 30 if(to[i]!=fa[x]) 31 { 32 dep[to[i]]=dep[x]+1,fa[to[i]]=x; 33 dfs(to[i]);sz[x]+=sz[to[i]]; 34 } 35 } 36 void Dfs(int x,int anc) 37 { 38 int hvs=0;hsh[x]=++cnt,bl[x]=anc; 39 for(int i=fst[x];i;i=nxt[i]) 40 if(to[i]!=fa[x]&&sz[to[i]]>sz[hvs]) hvs=to[i]; 41 if(!hvs) return ; 42 Dfs(hvs,anc); 43 for(int i=fst[x];i;i=nxt[i]) 44 if(to[i]!=fa[x]&&to[i]!=hvs) Dfs(to[i],to[i]); 45 } 46 void upd(int k) {sum[k]=sum[s[k][0]]+sum[s[k][1]],mx[k]=max(mx[s[k][0]],mx[s[k][1]]);} 47 void mdf(int &k,int l,int r,int x,int w) 48 { 49 if(!k) k=++tot,s[k][0]=s[k][1]=sum[k]=mx[k]=0; 50 //cout<<k<<" "<<l<<" "<<r<<" "<<x<<" "<<w<<" "<<sum[4]<<endl; 51 if(l==r) {sum[k]=mx[k]=w;return ;} 52 int mid=(l+r)>>1; 53 //system("pause"); 54 if(x<=mid) mdf(s[k][0],l,mid,x,w); 55 else mdf(s[k][1],mid+1,r,x,w); 56 upd(k); 57 } 58 int query(int k,int l,int r,int a,int b,int x) 59 { 60 if(!k) return 0; 61 //cout<<k<<" "<<l<<" "<<r<<" "<<a<<" "<<b<<" "<<mx[k]<<endl; 62 //cout<<k<<" "<<a<<" "<<b<<" "<<sum[k]<<endl; 63 if(l==a&&r==b) return x==1?sum[k]:mx[k]; 64 int mid=(l+r)>>1; 65 if(b<=mid) return query(s[k][0],l,mid,a,b,x); 66 else if(a>mid) return query(s[k][1],mid+1,r,a,b,x); 67 else if(x) return query(s[k][0],l,mid,a,mid,x)+query(s[k][1],mid+1,r,mid+1,b,x); 68 else return max(query(s[k][0],l,mid,a,mid,x),query(s[k][1],mid+1,r,mid+1,b,x)); 69 } 70 int work(int a,int b,int t,int x) 71 { 72 int res=0; 73 //cout<<t<<endl; 74 while(bl[a]!=bl[b]) 75 { 76 //cout<<a<<" "<<b<<" "<<x<<endl; 77 if(dep[bl[a]]<dep[bl[b]]) swap(a,b); 78 if(x) res+=query(t,1,n,hsh[bl[a]],hsh[a],x); 79 else res=max(res,query(t,1,n,hsh[bl[a]],hsh[a],x)); 80 a=fa[bl[a]]; 81 } 82 //cout<<res<<endl; 83 if(x) res+=query(t,1,n,min(hsh[a],hsh[b]),max(hsh[b],hsh[a]),x); 84 else res=max(res,query(t,1,n,min(hsh[a],hsh[b]),max(hsh[b],hsh[a]),x)); 85 return res; 86 } 87 int main() 88 { 89 n=read(),q=read();int a,b; 90 for(int i=1;i<=n;i++) val[i]=read(),c[i]=read(); 91 for(int i=1;i<n;i++) {a=read(),b=read();add(a,b);add(b,a);} 92 fa[1]=1;dfs(1);cnt=0;Dfs(1,1); 93 for(int i=1;i<=n;i++) mdf(rt[c[i]],1,n,hsh[i],val[i]); 94 //cout<<sum[4]<<endl; 95 while(q--) 96 { 97 scanf("%s",ch); 98 if(ch[0]=='C'&&ch[1]=='C') {a=read(),b=read();mdf(rt[c[a]],1,n,hsh[a],0);c[a]=b;mdf(rt[c[a]],1,n,hsh[a],val[a]);} 99 if(ch[0]=='C'&&ch[1]=='W') {a=read(),b=read();mdf(rt[c[a]],1,n,hsh[a],b);val[a]=b;} 100 if(ch[0]=='Q'&&ch[1]=='S') {a=read(),b=read();printf("%d\n",work(a,b,rt[c[a]],1));} 101 if(ch[0]=='Q'&&ch[1]=='M') {a=read(),b=read();printf("%d\n",work(a,b,rt[c[a]],0));} 102 } 103 }