• BZOJ4389 : ZYB and Trees


    Link-Cut Tree维护。

    每个点x维护以下信息:

    v:这个点的点权

    s:实链上的信息和

    st:子树信息和(不包括链上)

    sa:子树+链上的信息和

    as:所有虚儿子的sa的和

    则有

    s[x]=v[x]+s[son[x][0]]+s[son[x][1]]

    st[x]=as[x]+st[son[x][0]]+st[son[x][1]]

    sa[x]=s[x]+st[x]

    在access以及link的时候,涉及到虚实边的切换,在这个时候顺带维护一下as即可。

    查询以x为根时y子树信息和的时候,将x作为根,然后access(y),此时答案=as[y]+v[y]。

    时间复杂度$O(mlog n)$。

    #include<cstdio>
    #define N 200010
    typedef long long ll;
    int n,m,i,op,x,y,z;
    int f[N],son[N][2],tmp[N],c[N];bool rev[N];
    ll v[N],s[N],mx[N],tc[N],ta[N];
    ll st[N],sa[N],as[N];
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline void umax(ll&a,ll b){if(a<b)a=b;}
    inline void swap(int&a,int&b){int c=a;a=b;b=c;}
    inline bool isroot(int x){return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;}
    inline void rev1(int x){if(!x)return;swap(son[x][0],son[x][1]);rev[x]^=1;}
    inline void col1(int x,ll y){
      if(!x)return;
      v[x]=mx[x]=tc[x]=y;
      s[x]=y*c[x];
      ta[x]=0;
      sa[x]=s[x]+st[x];
    }
    inline void add1(int x,ll y){
      if(!x)return;
      v[x]+=y;
      s[x]+=y*c[x];
      mx[x]+=y;
      if(tc[x])tc[x]+=y;else ta[x]+=y;
      sa[x]=s[x]+st[x];
    }
    inline void pb(int x){
      if(rev[x])rev1(son[x][0]),rev1(son[x][1]),rev[x]=0;
      if(tc[x])col1(son[x][0],tc[x]),col1(son[x][1],tc[x]),tc[x]=0;
      if(ta[x])add1(son[x][0],ta[x]),add1(son[x][1],ta[x]),ta[x]=0;
    }
    inline void up(int x){
      s[x]=mx[x]=v[x];c[x]=1;
      st[x]=as[x];
      for(int i=0;i<2;i++){
        int y=son[x][i];
        if(y){
          c[x]+=c[y];
          s[x]+=s[y];
          umax(mx[x],mx[y]);
          st[x]+=st[y];
        }
      }
      sa[x]=s[x]+st[x];
    }
    inline void rotate(int x){
      int y=f[x],w=son[y][1]==x;
      son[y][w]=son[x][w^1];
      if(son[x][w^1])f[son[x][w^1]]=y;
      if(f[y]){
        int z=f[y];
        if(son[z][0]==y)son[z][0]=x;else if(son[z][1]==y)son[z][1]=x;
      }
      f[x]=f[y];f[y]=x;son[x][w^1]=y;up(y);
    }
    inline void splay(int x){
      int s=1,i=x,y;tmp[1]=i;
      while(!isroot(i))tmp[++s]=i=f[i];
      while(s)pb(tmp[s--]);
      while(!isroot(x)){
        y=f[x];
        if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
        rotate(x);
      }
      up(x);
    }
    inline void access(int x){
      for(int y=0;x;y=x,x=f[x]){
        splay(x);
        if(son[x][1])as[x]+=sa[son[x][1]];
        if(son[x][1]=y)as[x]-=sa[y];
        up(x);
      }
    }
    inline void makeroot(int x){access(x);splay(x);rev1(x);}
    inline void link(int x,int y){
      makeroot(x);
      makeroot(y);
      as[y]+=sa[x];
      f[x]=y;
      access(x);
    }
    inline void cutf(int x){access(x);splay(x);f[son[x][0]]=0;son[x][0]=0;up(x);}
    inline void cut(int x,int y){makeroot(x);cutf(y);}
    inline void col(int x,int y,int z){makeroot(x);access(y);splay(y);col1(y,z);}
    inline void add(int x,int y,int z){makeroot(x);access(y);splay(y);add1(y,z);}
    inline ll chainsum(int x,int y){makeroot(x);access(y);splay(y);return s[y];}
    inline ll chainmax(int x,int y){makeroot(x);access(y);splay(y);return mx[y];}
    inline ll subtreesum(int x,int y){makeroot(x);access(y);splay(y);return as[y]+v[y];}
    int main(){
      read(n);
      for(i=1;i<=n;i++)read(x),v[i]=s[i]=mx[i]=sa[i]=x,c[i]=1;
      for(i=2;i<=n;i++)read(x),link(x,i);
      read(m);
      while(m--){
        read(op),read(x),read(y);
        if(op==1)read(z),add(x,y,z);
        if(op==2)read(z),col(x,y,z);
        if(op==3)printf("%lld
    ",subtreesum(x,y));
        if(op==4)printf("%lld
    ",chainmax(x,y));
        if(op==5)printf("%lld
    ",chainsum(x,y));
        if(op==6)link(x,y);
        if(op==7)cut(x,y);
      }
      return 0;
    }
    

      

  • 相关阅读:
    windows下用python转换markdown到html
    windows下安装pip和easy_install
    Getting Real 摘记
    使iis支持asp.net扩展
    Linux IO模型
    kdissert:linux下的自由脑图软件
    debian下配置双核cpu
    内核:为了fan的健康,我的重新编译记录
    科研在每个人的生活中
    Donald Ervin Knuth:最年轻的图灵奖高德纳
  • 原文地址:https://www.cnblogs.com/clrs97/p/5104233.html
Copyright © 2020-2023  润新知