zoukankan      html  css  js  c++  java
  • [bzoj1036]:[ZJOI2008]树的统计Count(树链剖分)

    传送门
    十分裸的一个树链剖分,这也是我第一次过树剖题,好激动!
    关于这个算法我不多说,自己百度。
    代码:

    /**************************************************************
        Problem: 1036
        User: stone41123
        Language: C++
        Result: Accepted
        Time:2484 ms
        Memory:5676 kb
    ****************************************************************/
     
    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0;char ch=' ';int f=1;
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')f=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    struct edge{
        int to,next;
    }e[60001];
    int n,tot,q;
    int v[30001];
    int head[30001];
    inline void addedge(int x,int y){
        e[++tot].to=y;e[tot].next=head[x];head[x]=tot;
    }
    int father[30001];
    int size[30001];
    int top[30001];
    int heavy[30001];
    int dep[30001];
    void dfs1(int x,int fa){
        father[x]=fa;
        size[x]=1;
        dep[x]=dep[fa]+1;
        for(int i=head[x];i;i=e[i].next){
            int u=e[i].to;
            if(u==fa)continue;
            dfs1(u,x);
            size[x]+=size[u];
            if(size[u]>size[heavy[x]]){
                heavy[x]=u;
            }
        }
    }
    int a[30001];
    int mp[30001];
    int cnt;
    int id[30001];
    void dfs2(int x,int first){
        top[x]=first;
        id[++cnt]=x;
        mp[x]=cnt;
        a[cnt]=v[x];
        if(size[x]==1){
            return;
        }
        dfs2(heavy[x],first);
        for(int i=head[x];i;i=e[i].next){
            int u=e[i].to;
            if(u==heavy[x]||u==father[x]){
                continue;
            }
            dfs2(u,u);
        }
    }
    int sum[30001*4];
    int mx[30001*4];
    inline void pushup(int rt){
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
    }
    void build(int rt,int l,int r){
        if(l==r){
            sum[rt]=mx[rt]=a[l];
            return;
        }
        int mid=(l+r)>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
        pushup(rt);
    }
    void update(int rt,int l,int r,int pos,int x){
        if(l==r){
            sum[rt]=mx[rt]=x;
            return;
        }
        int mid=(l+r)>>1;
        if(pos<=mid)update(rt<<1,l,mid,pos,x);
        else update(rt<<1|1,mid+1,r,pos,x);
        pushup(rt);
    }
    int qmax(int rt,int l,int r,int L,int R){
        if(L<=l&&r<=R){
            return mx[rt];
        }
        int mid=(l+r)>>1;
        int ans=-0x7fffffff;
        if(L<=mid)ans=max(ans,qmax(rt<<1,l,mid,L,R));
        if(mid+1<=R)ans=max(ans,qmax(rt<<1|1,mid+1,r,L,R));
        return ans;
    }
    int qsum(int rt,int l,int r,int L,int R){
        if(L<=l&&r<=R){
            return sum[rt];
        }
        int mid=(l+r)>>1;
        int ans=0;
        if(L<=mid)ans+=qsum(rt<<1,l,mid,L,R);
        if(mid+1<=R)ans+=qsum(rt<<1|1,mid+1,r,L,R);
        return ans;
    }
    int query_max(int x,int y){
        int ans=-0x7fffffff;
        int tx=top[x];
        int ty=top[y];
        while(tx!=ty){
            if(dep[tx]<dep[ty]){
                swap(x,y);swap(tx,ty);
            }
            ans=max(ans,qmax(1,1,n,mp[tx],mp[x]));
            x=father[tx];
            tx=top[x];
        }
        if(dep[x]<dep[y]){
            swap(x,y);swap(tx,ty);
        }
        return max(ans,qmax(1,1,n,mp[y],mp[x]));
    }
    int query_sum(int x,int y){
        int ans=0;
        int tx=top[x];
        int ty=top[y];
        while(tx!=ty){
            if(dep[tx]<dep[ty]){
                swap(x,y);swap(tx,ty);
            }
            ans+=qsum(1,1,n,mp[tx],mp[x]);
            x=father[tx];
            tx=top[x];
        }
        if(dep[x]<dep[y]){
            swap(x,y);swap(tx,ty);
        }
        return ans+qsum(1,1,n,mp[y],mp[x]);
    }
    int main(){
        n=read();
        for(int i=1;i<n;i++){
            int x=read(),y=read();
            addedge(x,y);addedge(y,x);
        }
        for(int i=1;i<=n;i++)v[i]=read();
        q=read();
        dfs1(1,0);
        dfs2(1,1);
        build(1,1,n);
        char cmp0[20]="CHANGE";
        char cmp1[20]="QMAX";
        char cmp2[20]="QSUM";
        for(int i=1;i<=q;i++){
            char s[20];
            scanf("%s",s);
            if(strcmp(cmp0,s)==0){
                int pos=read(),x=read();
                update(1,1,n,mp[pos],x);
            }
            else if(strcmp(cmp1,s)==0){
                int x=read(),y=read();
                printf("%d
    ",query_max(x,y));
            }
            else{
                int x=read(),y=read();
                printf("%d
    ",query_sum(x,y));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    javascript 高级程序设计 二
    javascript 高级程序设计 一
    js 立即执行函数
    thinkphp验证器
    thinkphp5 行为(钩子)扩展
    thinkphp5控制器
    修改tp5的默认配置文件的位置
    thinkphp5 model 模型与Db
    API接口设计,rest,soap
    tp5的路由
  • 原文地址:https://www.cnblogs.com/stone41123/p/7601079.html
Copyright © 2011-2022 走看看