【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 }