首页 写随笔

cdcq(本博客废弃!现用博客:https://www.cnblogs.com/cdcq/)

本博客废弃!现用博客:https://www.cnblogs.com/cdcq/

导航

【BZOJ4817】【SDOI2017】树点染色

不算学会lct。。。。。。

原题:

Bob有一棵n个点的有根树,其中1号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。定义一条路
径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。Bob可能会进行这几种操作:
1 x:
把点x到根节点的路径上所有的点染上一种没有用过的新颜色。
2 x y:
求x到y的路径的权值。
3 x y:
在以x为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。
Bob一共会进行m次操作
1<=n,m<=100000
 
并不严格的lct,只需要access操作,而且链存在的意义也不是为了优化时间复杂度
恩所以一开始每个点都是一条链,表示每个点都是一个颜色
access就相当于点到根染成同一种颜色
求路径权值就在链上跳一跳即可
子树最大指的话就一开始就搞出dfs序和线段树,因为树的形态并没有改变,然后access的时候维护即可
代码:
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 using namespace std;
  7 int rd(){int z=0,mk=1;  char ch=getchar();
  8     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
  9     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
 10     return z*mk;
 11 }
 12 struct edg{int nxt,y;}e[210000];  int lk[110000],ltp=0;
 13 inline void ist(int x,int y){  e[++ltp].nxt=lk[x],lk[x]=ltp,e[ltp].y=y;}
 14 int n,m;
 15 int fth[110000],chd[110000][2],tpf[110000];
 16 int acst[110000][17],dp[110000],dod[110000],lod[110000],rod[110000],cod=0;
 17 int v[410000],vt[410000];
 18 void dfs(int x){
 19     dod[lod[x]=++cod]=x;
 20     for(int i=lk[x];i;i=e[i].nxt)if(e[i].y!=acst[x][0])
 21         acst[e[i].y][0]=fth[e[i].y]=x,dp[e[i].y]=dp[x]+1,dfs(e[i].y);
 22     rod[x]=cod;
 23 }
 24 int lca(int x,int y){
 25     if(dp[x]<dp[y])  swap(x,y);
 26     for(int i=0,j=dp[x]-dp[y];i<=16;++i)if((1<<i)&j)  x=acst[x][i];
 27     for(int i=16;i>=0;--i)if(acst[x][i]!=acst[y][i])
 28         x=acst[x][i],y=acst[y][i];
 29     if(x==y)  return x;
 30     return acst[x][0];
 31 }
 32 void pshd(int x){
 33     v[x<<1]+=vt[x],v[x<<1|1]+=vt[x];
 34     vt[x<<1]+=vt[x],vt[x<<1|1]+=vt[x];
 35     vt[x]=0;
 36 }
 37 void gtsgmttr(int x,int l,int r){
 38     if(l==r){  v[x]=dp[dod[l]]+1;  return ;}
 39     int md=(l+r)>>1;
 40     gtsgmttr(x<<1,l,md),gtsgmttr(x<<1|1,md+1,r);
 41     v[x]=max(v[x<<1],v[x<<1|1]);
 42 }
 43 void mdf(int x,int l,int r,int ql,int qr,int z){
 44     if(l==ql && r==qr){  v[x]+=z,vt[x]+=z;  return ;}
 45     int md=(l+r)>>1;  pshd(x);
 46     if(ql<=md && qr>md)  mdf(x<<1,l,md,ql,md,z),mdf(x<<1|1,md+1,r,md+1,qr,z);
 47     else if(qr<=md)  mdf(x<<1,l,md,ql,qr,z);
 48     else  mdf(x<<1|1,md+1,r,ql,qr,z);
 49     v[x]=max(v[x<<1],v[x<<1|1]);
 50 }
 51 int qur(int x,int l,int r,int ql,int qr){
 52     if(l==ql && r==qr)  return v[x];
 53     int md=(l+r)>>1;  pshd(x);
 54     if(ql<=md && qr>md)  return max(qur(x<<1,l,md,ql,md),qur(x<<1|1,md+1,r,md+1,qr));
 55     else if(qr<=md)  return qur(x<<1,l,md,ql,qr);
 56     else  return qur(x<<1|1,md+1,r,ql,qr);
 57 }
 58 inline bool isrt(int x){  return (chd[fth[x]][0]!=x)&(chd[fth[x]][1]!=x);}
 59 void pshu(int x){  tpf[x]=chd[x][0] ? tpf[chd[x][0]] : x;}
 60 void rtt(int x){
 61     int y=fth[x],z=fth[fth[x]],l,r;
 62     r=(chd[y][0]==x);  l=r^1;
 63     if(!isrt(y))  chd[z][chd[z][1]==y]=x;
 64     fth[x]=z,fth[y]=x,fth[chd[x][r]]=y;
 65     chd[y][l]=chd[x][r],chd[x][r]=y;
 66     pshu(y),pshu(x);
 67 }
 68 void sply(int x){
 69     while(!isrt(x)){
 70         int y=fth[x],z=fth[fth[x]];
 71         if(!isrt(y))  rtt((chd[y][0]==x)^(chd[z][0]==y) ? x : y);
 72         rtt(x);
 73     }
 74 }
 75 void accs(int x){
 76     int lst=0;
 77     while(x){
 78         sply(x);
 79         if(chd[x][1])  mdf(1,1,n,lod[tpf[chd[x][1]]],rod[tpf[chd[x][1]]],1);
 80         if(lst)  mdf(1,1,n,lod[tpf[lst]],rod[tpf[lst]],-1);
 81         chd[x][1]=lst,x=fth[lst=x];
 82     }
 83 }
 84 int gtnm(int x){
 85     int bwl=0;
 86     while(x){
 87         sply(x);
 88         x=fth[x],++bwl;
 89     }
 90     return bwl;
 91 }
 92 int cclt(int x,int y){
 93     int z=lca(x,y);
 94     return gtnm(x)+gtnm(y)-(gtnm(z)<<1)+1;
 95 }
 96 int main(){//freopen("ddd.in","r",stdin);
 97     int l,r,mk;
 98     cin>>n>>m;
 99     for(int i=1;i<n;++i)  l=rd(),r=rd(),ist(l,r),ist(r,l);
100     dfs(1),gtsgmttr(1,1,n);
101     for(int i=1;i<=n;++i)  tpf[i]=i;
102     for(int i=1;i<=n;++i)for(int j=1;(1<<j)<=dp[i];++j)
103         acst[i][j]=acst[acst[i][j-1]][j-1];
104     while(m--){
105         mk=rd();
106         if(mk==1)  accs(rd());
107         else if(mk==2)  printf("%d\n",cclt(rd(),rd()));
108         else  l=rd(),printf("%d\n",qur(1,1,n,lod[l],rod[l]));
109     }
110     return 0;
111 }
View Code

 

posted on 2017-05-17 20:41  cdcq_old  阅读(319)  评论(0编辑  收藏  举报