zoukankan      html  css  js  c++  java
  • bzoj2631: tree lct

    这道题需要注意的就是标记的传递 规定先传乘法标记再传加法标记就好了

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL unsigned int
    using namespace std;
    const int M=100007,mod=51061; 
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    LL v[M],sum[M],tag[M],mt[M];
    int c[M][2],fa[M],rev[M],size[M];
    int n,m;
    bool isrt(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
    void up(int x){
        int l=c[x][0],r=c[x][1];
        sum[x]=(sum[l]+sum[r]+v[x])%mod;
        size[x]=size[l]+size[r]+1;
    }
    void add(int x,int m,int w){
        if(!x) return ;
        v[x]=(v[x]*m+w)%mod;
        sum[x]=(sum[x]*m+w*size[x])%mod;
        tag[x]=(tag[x]*m+w)%mod;
        mt[x]=mt[x]*m%mod;
    }
    void down(int x){
        int l=c[x][0],r=c[x][1];
        if(rev[x]){
            rev[x]=0; rev[l]^=1; rev[r]^=1;
            swap(c[x][0],c[x][1]);
        }
        if(tag[x]||mt[x]!=1){
            add(l,mt[x],tag[x]);
            add(r,mt[x],tag[x]);
            tag[x]=0; mt[x]=1;
        }
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],l=0,r=1;
        if(c[y][1]==x) l=1,r=0;
        if(!isrt(y)) c[z][c[z][1]==y]=x;
        fa[y]=x; fa[x]=z; fa[c[x][r]]=y;
        c[y][l]=c[x][r]; c[x][r]=y;
        up(y); up(x);
    }
    int st[M],top;
    void splay(int x){
        st[++top]=x; for(int i=x;!isrt(i);i=fa[i]) st[++top]=fa[i];
        while(top) down(st[top--]);
        while(!isrt(x)){
            int y=fa[x],z=fa[y];
            if(!isrt(y)){
                if(c[z][0]==y^c[y][0]==x) rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
    }
    void acs(int x0){
        for(int x=x0,y=0;x;splay(x),c[x][1]=y,up(x),y=x,x=fa[x]);
        splay(x0);
    }
    void mrt(int x){acs(x); rev[x]^=1;}
    void link(int x,int y){mrt(x); fa[x]=y;}
    void split(int x,int y){mrt(x); acs(y);}
    void cut(int x,int y){split(x,y); c[y][0]=fa[x]=0;}
    int main()
    {
        int x,y,w;
        char ch[5];
        n=read(); m=read();
        for(int i=1;i<=n;i++) size[i]=v[i]=mt[i]=sum[i]=1;
        for(int i=1;i<n;i++) x=read(),y=read(),link(x,y);
        for(int i=1;i<=m;i++){
            scanf("%s",ch); x=read(); y=read();
            if(ch[0]=='+') w=read(),split(y,x),add(x,1,w);
            else if(ch[0]=='-') cut(x,y),x=read(),y=read(),link(x,y);
            else if(ch[0]=='*') w=read(),split(y,x),add(x,w,0);
            else split(y,x),printf("%d
    ",sum[x]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    设计模式-抽象工厂模式
    装修预算-资料收集
    SQL中存储过程和函数的区别
    View
    数据表优化
    Entity Framework 基础
    html5标准
    JS整数验证
    vue 页面切换从右侧切入效果
    vue动态设置Iview的多个Input组件自动获取焦点
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7002888.html
Copyright © 2011-2022 走看看