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 }
View Code

 

posted @ 2018-08-31 18:20  jack_yyc  阅读(123)  评论(0编辑  收藏  举报