首页 > 代码库 > Bzoj4817 [Sdoi2017]树点涂色

Bzoj4817 [Sdoi2017]树点涂色

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 301  Solved: 182

Description

Bob有一棵n个点的有根树,其中1号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。定义一条路
径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。Bob可能会进行这几种操作:
1 x:
把点x到根节点的路径上所有的点染上一种没有用过的新颜色。
2 x y:
求x到y的路径的权值。
3 x y:
在以x为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。
Bob一共会进行m次操作
 

Input

第一行两个数n,m。
接下来n-1行,每行两个数a,b,表示a与b之间有一条边。
接下来m行,表示操作,格式见题目描述
1<=n,m<=100000
 

Output

每当出现2,3操作,输出一行。
如果是2操作,输出一个数表示路径的权值
如果是3操作,输出一个数表示权值的最大值
 

Sample Input

5 6
1 2
2 3
3 4
3 5
2 4 5
3 3
1 4
2 4 5
1 5
2 4 5

Sample Output

3
4
2
2

HINT

 

Source

鸣谢infinityedge上传

 

Bzoj3779 重组病毒 ←这个的弱化版

树 线段树 LCT LCA

基本上和上面那道题一样

查询链上颜色树的时候做差分即可,$ ans=val(x)+val(y)-2*val(LCA(x,y))+1 $

 

  1 /*by SilverN*/  2 #include<algorithm>  3 #include<iostream>  4 #include<cstring>  5 #include<cstdio>  6 #include<cmath>  7 #include<vector>  8 #define LL long long  9 using namespace std; 10 const int mxn=100010; 11 int read(){ 12     int x=0,f=1;char ch=getchar(); 13     while(ch<0 || ch>9){if(ch==-)f=-1;ch=getchar();} 14     while(ch>=0 && ch<=9){x=x*10+ch-0;ch=getchar();} 15     return x*f; 16 } 17 struct edge{ 18     int v,nxt; 19 }e[mxn<<1]; 20 int hd[mxn],mct=0; 21 void add_edge(int u,int v){ 22     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return; 23 } 24 namespace TC{ 25     struct node{ 26         int fa,top,son; 27         int sz; 28     }t[mxn]; 29     int dep[mxn],ind[mxn],out[mxn],dtime; 30     int mp[mxn]; 31     void DFS(int u,int ff){ 32         dep[u]=dep[ff]+1; 33         t[u].sz++; 34         for(int i=hd[u],v;i;i=e[i].nxt){ 35             if(e[i].v==ff)continue; 36             v=e[i].v; 37             t[v].fa=u; 38             DFS(v,u); 39             t[u].sz+=t[v].sz; 40             if(t[v].sz>t[t[u].son].sz)t[u].son=v; 41         } 42         return; 43     } 44     void DFS2(int u,int top){ 45         ind[u]=++dtime; 46         mp[dtime]=u; 47         t[u].top=top; 48         if(t[u].son){ 49             DFS2(t[u].son,top); 50             for(int i=hd[u];i;i=e[i].nxt){ 51                 if(e[i].v==t[u].son || e[i].v==t[u].fa)continue; 52                 DFS2(e[i].v,e[i].v); 53             } 54         } 55         out[u]=dtime; 56         return; 57     } 58     int LCA(int x,int y){ 59         while(t[x].top!=t[y].top){ 60             if(dep[t[x].top]<dep[t[y].top])swap(x,y); 61             x=t[t[x].top].fa; 62         } 63         if(dep[x]<dep[y])return x; 64         else return y; 65     } 66 } 67 int n,m,nowroot; 68 struct SGT{ 69     #define lc rt<<1 70     #define rc rt<<1|1 71     struct node{ 72         LL smm,mk,mx; 73     }t[mxn<<2]; 74     void pushup(int rt){ 75         t[rt].smm=t[lc].smm+t[rc].smm; 76         t[rt].mx=max(t[lc].mx,t[rc].mx); 77         return; 78     } 79     inline void PD(int l,int r,int rt){ 80         if(t[rt].mk){ 81             t[lc].mk+=t[rt].mk; 82             t[rc].mk+=t[rt].mk; 83             int mid=(l+r)>>1; 84             t[lc].smm+=t[rt].mk*(LL)(mid-l+1); 85             t[rc].smm+=t[rt].mk*(LL)(r-mid); 86             t[lc].mx+=t[rt].mk;t[rc].mx+=t[rt].mk; 87             t[rt].mk=0; 88         } 89         return; 90     } 91     void Build(int l,int r,int rt){ 92         if(l==r){ 93             t[rt].smm=t[rt].mx=TC::dep[TC::mp[l]];    return; 94         } 95         int mid=(l+r)>>1; 96         Build(l,mid,lc);Build(mid+1,r,rc); 97         pushup(rt); 98         return; 99     }100     void update(int L,int R,int v,int l,int r,int rt){101         if(L>R)return;102         if(L<=l && r<=R){103             t[rt].mk+=v;104             t[rt].smm+=(LL)v*(r-l+1);105             t[rt].mx+=v;106             return;107         }108         PD(l,r,rt);109         int mid=(l+r)>>1;110         if(L<=mid)update(L,R,v,l,mid,lc);111         if(R>mid)update(L,R,v,mid+1,r,rc);112         pushup(rt);113         return;114     }115     LL qmax(int L,int R,int l,int r,int rt){116         if(L>R)return -1e9;117         if(L<=l && r<=R){return t[rt].mx;}118         PD(l,r,rt);119         int mid=(l+r)>>1;120         LL res=-1e9;121         if(L<=mid)res=max(res,qmax(L,R,l,mid,lc));122         if(R>mid)res=max(res,qmax(L,R,mid+1,r,rc));123         return res;124     }125     LL qsum(int p,int l,int r,int rt){126         if(l==r){return t[rt].smm;}127         PD(l,r,rt);128         LL res=0;129         int mid=(l+r)>>1;130         if(p<=mid)res=qsum(p,l,mid,lc);131         else res=qsum(p,mid+1,r,rc);132         pushup(rt);133         return res;134     }135     void Q_UPD(int x,int v){136         using namespace TC;        137         update(ind[x],out[x],v,1,n,1);138         return;139     }140     LL Query(int x){141         using namespace TC;142 //        printf("___:%d\n",x);143         int y=read();144         int tmp=TC::LCA(x,y);145         LL ans=qsum(ind[x],1,n,1)+qsum(ind[y],1,n,1)-2*qsum(ind[tmp],1,n,1)+1;146         printf("%lld\n",ans);147         return ans;148     }149     LL Q_max(int x){150         using namespace TC;151         LL ans=0;152         ans=qmax(ind[x],out[x],1,n,1);153         printf("%lld\n",ans);154         return ans;155     }156     #undef lc157     #undef rc158 }sgt;159 struct LCT{160     int ch[mxn][2],fa[mxn];161     bool rev[mxn];162     int st[mxn],top;163     inline bool isroot(int x){return (ch[fa[x]][0]!=x && ch[fa[x]][1]!=x);}164     void PD(int rt){165         if(rev[rt]){166             rev[ch[rt][0]]^=1;    rev[ch[rt][1]]^=1;167             swap(ch[rt][0],ch[rt][1]);168             rev[rt]^=1;169         }170         return;171     }172     void rotate(int x){173         int y=fa[x],z=fa[y],lc,rc;174         if(ch[y][0]==x)lc=0;else lc=1; rc=lc^1;175         if(!isroot(y)) ch[z][ch[z][1]==y]=x;176         fa[x]=z;fa[y]=x;177         fa[ch[x][rc]]=y;178         ch[y][lc]=ch[x][rc]; ch[x][rc]=y;179         return;180     }181     void Splay(int x){182         st[top=1]=x;183         for(int i=x;!isroot(i);i=fa[i])    st[++top]=fa[i];184         while(top)PD(st[top--]);185         while(!isroot(x)){186             int y=fa[x],z=fa[y];187             if(!isroot(y)){188                 if((ch[z][0]==y)^(ch[y][0]==x))rotate(x);189                 else rotate(y);190             }191             rotate(x);192         }193     }194     void access(int x){195         for(int y=0;x;x=fa[x]){196             Splay(x);197             if(ch[x][1]){198                 int now=ch[x][1];199                 PD(now);200                 while(ch[now][0]){now=ch[now][0];PD(now);}201                 sgt.Q_UPD(now,1);202             }203             if(y){204                 int now=y;205                 PD(now);206                 while(ch[now][0]){now=ch[now][0];PD(now);}207                 sgt.Q_UPD(now,-1);208             }209             ch[x][1]=y;210             y=x;211         }212         return;213     }214 /*    void mkroot(int x){215         access(x);Splay(x);216         rev[x]^=1;217         nowroot=x;218         return;219     }*/220 }LT;221 void solve(){222     int x,opt;223     while(m--){224         scanf("%d%d",&opt,&x);225         if(opt==1){LT.access(x);continue;}226         if(opt==2){sgt.Query(x);continue;}227         if(opt==3){sgt.Q_max(x);continue;}228 //        else Debug();229     }230     return;231 }232 int main(){233 //    freopen("paint1.in","r",stdin);234 //    freopen("out2.txt","w",stdout);235     int i,j;236     n=read();m=read();237     int u,v;238     for(i=1;i<n;i++){239         u=read();v=read();240         add_edge(u,v);add_edge(v,u);241     }242     TC::DFS(1,0);243     TC::DFS2(1,1);244     for(i=1;i<=n;i++) LT.fa[i]=TC::t[i].fa;    245     sgt.Build(1,n,1);246     solve();247     return 0;248 }

 

Bzoj4817 [Sdoi2017]树点涂色