zoukankan      html  css  js  c++  java
  • bzoj1036: [ZJOI2008]树的统计Count link-cut-tree版

    题目传送门

    这 算是link-cut-tree裸题啊 不过以前好像没有写过单点修改..............

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int M=50007;
    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;
    }
    int n,m,c[M][2],fa[M],a[M],b[M];
    LL v[M],sum[M],mx[M];
    bool rev[M];
    bool isrt(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
    void up(int x){
        if(!x) return ;
        mx[x]=v[x]; sum[x]=v[x];
        int l=c[x][0],r=c[x][1];
        if(l) mx[x]=max(mx[x],mx[l]),sum[x]+=sum[l];
        if(r) mx[x]=max(mx[x],mx[r]),sum[x]+=sum[r];
    }
    void down(int x){
        if(!rev[x]) return ;
        rev[x]=0;
        int l=c[x][0],r=c[x][1];
        if(l) swap(c[l][0],c[l][1]),rev[l]^=1;
        if(r) swap(c[r][0],c[r][1]),rev[r]^=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=0,S;
    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); swap(c[x][0],c[x][1]); rev[x]^=1;}
    void link(int x,int y){mrt(x); fa[x]=y;}
    void spl(int x,int y){mrt(x); acs(y);}
    int main()
    {
        int x,y;
        n=read();
        for(int i=1;i<n;i++) a[i]=read(),b[i]=read();
        for(int i=1;i<=n;i++) v[i]=read();
        for(int i=1;i<n;i++) link(a[i],b[i]);
        m=read();
        char ch[15];
        for(int i=1;i<=m;i++){
            scanf("%s",ch); x=read(); y=read();
            if(ch[1]=='H') acs(x),v[x]=y;
            if(ch[1]=='S') spl(x,y),printf("%lld
    ",sum[y]);
            if(ch[1]=='M') spl(x,y),printf("%lld
    ",mx[y]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Ubuntu16.04下安装搜狗输入法及实现中英文转换问题
    OLED的使用-4线SPI驱动
    maven的pom.xml多个仓库配置
    Eclipse快捷键大全
    ubuntu18安装docker
    运行docker大致流程
    docker常用命令
    使用webhooks进行代码的自动化部署
    springboot整合dubbo+zookeeper最新详细
    那些好用到手软的软件和网站
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7084849.html
Copyright © 2011-2022 走看看