zoukankan      html  css  js  c++  java
  • bzoj 1036: [ZJOI2008]树的统计Count

    http://www.lydsy.com/JudgeOnline/problem.php?id=1036

    大约是个树剖裸题,然后用lct水了一下

    wa数发后突然意识到有负数,改了一下数组初始值,还是wa,woc!读入优化没判负数╮(╯_╰)╭囧

    /**************************************************************
        Problem: 1036
        User: 11101001
        Language: C++
        Result: Accepted
        Time:4492 ms
        Memory:3516 kb
    ****************************************************************/
     
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    const int maxn =60007;
    int n,m;
    int top=0;
    int ch[maxn][2],fa[maxn],stack[maxn];
    int ans[maxn],maxx[maxn],v[maxn];
    bool rev[maxn];
    inline int read() {
        int x=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c<='9'&&c>='0') x=x*10+c-'0',c=getchar();
        return x*f;
    }
    void update(int x) {
        ans[x]=ans[ch[x][1]]+ans[ch[x][0]]+v[x];    
        maxx[x]=std::max(maxx[ch[x][1]],std::max(maxx[ch[x][0]],v[x]));
    }
    bool isroot(int x) {
        return ch[fa[x]][1]!=x&&ch[fa[x]][0]!=x;
    }
    void pushdown(int x) {
        if(rev[x]) {
            rev[x]^=1;
            rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;std::swap(ch[x][1],ch[x][0]);
        }
    }
    void rotate(int x) {
        int y=fa[x],z=fa[y],d=(ch[y][1]==x)^1;
        if(!isroot(y)) ch[z][ch[z][1]==y]=x;
        fa[x]=z;
        ch[y][d^1]=ch[x][d],fa[ch[x][d]]=y;
        ch[x][d]=y;fa[y]=x;
        update(y);update(x);
    }
    void splay(int x) {
        stack[++top]=x;
        for(int i=x;!isroot(i);i=fa[i]) stack[++top]=fa[i];
        while(top)pushdown(stack[top--]);
        while(!isroot(x)) {
            int y=fa[x],z=fa[y];
            if(!isroot(y)) {
                if(ch[y][1]==x^ch[z][1]==y)rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
        return ;
    }
    void access(int x) {
        for(int i=0;x;i=x,x=fa[x]) { 
            splay(x);
            ch[x][1]=i;update(x);
        }
    }
    void makeroot(int x) {
        access(x),splay(x);rev[x]^=1;
    }
    void split(int x,int y) {
        makeroot(x),access(y);
        return splay(y);
    }
    int query(int x,int y,int op) {
        split(x,y);
        if(op)return ans[y];
        return maxx[y];
    }
    void modify(int x,int y) {
        access(x),splay(x),v[x]=y;
        return update(x);
    }
    struct wrj{
        int num,head[maxn];
        wrj() {
            num=0;memset(head,0,sizeof head);
        }
        struct node{
            int v,next;
        }edge[maxn];
        void add_edge(int x,int y) {
            edge[++num].v=y;edge[num].next=head[x];head[x]=num;
        }
        void dfs(int x) {
            for(int i=head[x];i;i=edge[i].next) {
                int vv=edge[i].v;
                if(vv!=fa[x]) {
                    fa[vv]=x;
                    dfs(vv);
                }
            }
        }
    }gg;
    int main() {
        n=read();
        std::memset(maxx,-0x3f,sizeof(maxx));
        for(int a,b,i=1;i<n;++i) {
            a=read(),b=read();gg.add_edge(a,b);gg.add_edge(b,a);
        }
        for(int i=1;i<=n;++i) {
            v[i]=read();
        }
        gg.dfs(1);
        m=read();
        char c[70];
        for(int a,b;m;m--) {
            scanf("%s",c),a=read(),b=read();
            if(c[1]=='S') {
                printf("%d
    ",query(a,b,1));    
            }
            else if(c[1]=='M'){
                printf("%d
    ",query(a,b,0));    
            }
            else modify(a,b);
        }
        return 0;
    }
  • 相关阅读:
    面试题11:旋转数组的最小数字(C++)
    2019.9.20学习内容及随堂笔记
    2019.9.19学习内容及小结
    2019.9.18(day39)学习内容及小结
    2019.9.17学习内容及随堂笔记
    2019.9.16学习内容及随堂笔记
    2019.9.12(day36)学习内容及笔记
    2019.9.11学习内容及随堂笔记
    2019.9.10学习内容及随堂笔记
    2019.9.9学习内容及随堂笔记
  • 原文地址:https://www.cnblogs.com/sssy/p/8150940.html
Copyright © 2011-2022 走看看