zoukankan      html  css  js  c++  java
  • 【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
    ",cclt(rd(),rd()));
    108         else  l=rd(),printf("%d
    ",qur(1,1,n,lod[l],rod[l]));
    109     }
    110     return 0;
    111 }
    View Code
  • 相关阅读:
    linux系统中将一列数据转换为若干列数据(列的顺序不变)
    linux系统中将矩形数据转换为一行、一列的形式
    linux系统中实现文本转置。
    linux shell 如何将多列数据变为一行数据
    linux系统中如何将一行数据变为一列
    bash: unlzma: command not found...
    linux系统中实现对行的批量替换
    linux系统中对指定行的字符串进行替换
    linux系统中对指定列的数据中的字符串进行替换
    linux系统中如何将每行特定数目字符后的字符替换为指定字符
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6869463.html
Copyright © 2011-2022 走看看