• ZJOI2008 树的统计 树链剖分学习


    水题,这次都没有给我傻逼的机会了,1A过了。直接上代码了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define LL long long
    #define INF 0x3fffffff
    #define FOR(i,x,y)  for(int i = x;i < y;i ++)
    #define IFOR(i,x,y) for(int i = x;i > y;i --)
    #define lrt rt<<1
    #define rrt rt<<1|1
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    #define MAXN 33000
    
    using namespace std;
    
    int n,p;
    
    struct Edge{
        int u,v;
        int nt;
    }edge[MAXN<<1];
    
    int head[MAXN],edge_cnt;
    
    void add_edge(int u,int v){
        edge[edge_cnt].u = u;
        edge[edge_cnt].v = v;
        edge[edge_cnt].nt = head[u];
        head[u] = edge_cnt++;
    }
    
    int val0[MAXN];
    int fa[MAXN],sz[MAXN],son[MAXN],dep[MAXN],top[MAXN],w[MAXN],val[MAXN];
    int totw;
    
    void dfs1(int u,int father,int depth){
        fa[u] = father; dep[u] = depth; sz[u] = 1;
        int idd = -1,maxx = -1;
        for(int i = head[u];i != -1;i = edge[i].nt){
            int v = edge[i].v;
            if(v == father) continue;
            dfs1(v,u,depth+1);
            sz[u] += sz[v];
            if(maxx < sz[v])    {maxx = sz[v];idd = v;}
        }
        son[u] = idd;
    }
    
    void dfs2(int u,int father){
        if(son[u] == -1)    return;
        top[son[u]] = top[u];
        w[son[u]] = ++totw;
        val[totw] = val0[son[u]];
        dfs2(son[u],u);
        for(int i = head[u];i != -1;i = edge[i].nt){
            int v = edge[i].v;
            if(v == father) continue;
            if(v == son[u]) continue;
            top[v] = v;
            w[v] = ++totw;
            val[totw] = val0[v];
            dfs2(v,u);
        }
    }
    
    struct Tree{
        int l,r;
        int maxx,sum;
    }tree[MAXN<<2];
    
    void PushUp(int rt){
        tree[rt].maxx = max(tree[lrt].maxx,tree[rrt].maxx);
        tree[rt].sum = tree[lrt].sum + tree[rrt].sum;
    }
    
    void Build(int rt,int l,int r){
        tree[rt].l = l; tree[rt].r = r;
        if(l == r){
            tree[rt].maxx = tree[rt].sum = val[l];
            return;
        }
        int mid = (l+r)>>1;
        Build(lson);
        Build(rson);
        PushUp(rt);
    }
    
    void Modify(int rt,int x,int value){
        if(tree[rt].l == tree[rt].r){
            tree[rt].maxx = tree[rt].sum = value;
            return;
        }
        int mid = (tree[rt].l + tree[rt].r)>>1;
        if(x <= mid) Modify(lrt,x,value);
        else Modify(rrt,x,value);
        PushUp(rt);
    }
    
    int Q_Max(int rt,int l,int r){
        if(tree[rt].l == l && tree[rt].r == r){
            return tree[rt].maxx;
        }
        int mid = (tree[rt].l + tree[rt].r)>>1;
        if(r <= mid) return Q_Max(lrt,l,r);
        else if(l > mid) return Q_Max(rrt,l,r);
        else{
            return max(Q_Max(lson),Q_Max(rson));
        }
    }
    
    int Q_Sum(int rt,int l,int r){
        if(tree[rt].l == l && tree[rt].r == r){
            return tree[rt].sum;
        }
        int mid = (tree[rt].l + tree[rt].r)>>1;
        if(r <= mid) return Q_Sum(lrt,l,r);
        else if(l > mid) return Q_Sum(rrt,l,r);
        else{
            return Q_Sum(lson)+Q_Sum(rson);
        }
    }
    
    int Max(int l,int r){
        int ans = -INF;
        while(top[l] != top[r]){
            if(dep[top[l]] >= dep[top[r]]){
                ans = max(ans,Q_Max(1,w[top[l]],w[l]));
                l = fa[top[l]];
            }
            else{
                ans = max(ans,Q_Max(1,w[top[r]],w[r]));
                r = fa[top[r]];
            }
        }
        if(l == r)  ans = max(ans,Q_Max(1,w[l],w[r]));
        else if(dep[l] >= dep[r]){
            ans = max(ans,Q_Max(1,w[r],w[l]));
        }
        else ans = max(ans,Q_Max(1,w[l],w[r]));
        return ans;
    }
    
    int Sum(int l,int r){
        int ans = 0;
        while(top[l] != top[r]){
            if(dep[top[l]] >= dep[top[r]]){
                ans += Q_Sum(1,w[top[l]],w[l]);
                l = fa[top[l]];
            }
            else{
                ans += Q_Sum(1,w[top[r]],w[r]);
                r = fa[top[r]];
            }
        }
        if(l == r)  ans += Q_Sum(1,w[l],w[r]);
        else if(dep[l] >= dep[r]) ans += Q_Sum(1,w[r],w[l]);
        else ans += Q_Sum(1,w[l],w[r]);
        return ans;
    }
    
    int main()
    {
        //freopen("test.in","r",stdin);
        while(~scanf("%d",&n)){
            edge_cnt = 0;
            memset(head,-1,sizeof(head));
            FOR(i,1,n){
                int u,v;
                scanf("%d%d",&u,&v);
                add_edge(u,v);
                add_edge(v,u);
            }
            FOR(i,1,n+1)    scanf("%d",&val0[i]);
            dfs1(1,-1,1);
            totw = 0;
            top[1] = 1;
            val[1] = val0[1];
            w[1] = ++totw;
            dfs2(1,-1);
            Build(1,1,totw);
            scanf("%d",&p);
            char op[10];
            while(p--){
                scanf("%s",op);
                if(!strcmp(op,"CHANGE")){
                    int u,t;
                    scanf("%d%d",&u,&t);
                    Modify(1,w[u],t);
                }
                else if(!strcmp(op,"QMAX")){
                    int l,r;
                    scanf("%d%d",&l,&r);
                    printf("%d
    ",Max(l,r));
                }
                else{
                    int l,r;
                    scanf("%d%d",&l,&r);
                    printf("%d
    ",Sum(l,r));
                }
            }
        }
        return 0;
    }
    


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    常用工具-notepad++打开大文件卡死现象
    ORM框架之EntityFramework
    System.Data.Entity 无法引用的问题
    js 数组、对象转json 以及json转 数组、对象
    js中(function(){xxx})();写法解析以及function与!感叹号
    js 里面call()的使用
    Javascript继承机制的设计思想
    JS中let和var的区别
    利用JS实现图片的缓存
    实例详述FOR XML PATH用法
  • 原文地址:https://www.cnblogs.com/hqwhqwhq/p/4811882.html
Copyright © 2020-2023  润新知