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

    P2590 [ZJOI2008]树的统计

    虽然是入门树剖模板

    但是我终于1A了(大哭)

    懒得写啥了(逃

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    inline int Max(int a,int b){return a>b?a:b;}
    inline void Swap(int &a,int &b){a^=b^=a^=b;}
    #define N 30005
    int n,Q,Top[N],bgs[N],siz[N],fa[N],val[N];
    int ID,id[N],tmp[N],sum[N<<2],mxd[N<<2];
    int cnt,hd[N],nxt[N<<1],ed[N],poi[N<<1];
    #define lc o<<1
    #define rc o<<1|1
    #define mid (l+r)/2
    inline void adde(int x,int y){
        nxt[ed[x]]=++cnt; hd[x]=hd[x]?hd[x]:cnt;
        ed[x]=cnt; poi[cnt]=y;
    }
    inline void up(int o){
        sum[o]=sum[lc]+sum[rc];
        mxd[o]=Max(mxd[lc],mxd[rc]);
    }
    void build(int o,int l,int r){
        if(l==r){sum[o]=mxd[o]=tmp[l]; return ;}
        build(lc,l,mid); build(rc,mid+1,r); up(o);
    }
    void modi(int o,int l,int r,int x,int v){
        if(l==r){sum[o]=mxd[o]=v; return ;}
        if(x<=mid) modi(lc,l,mid,x,v);
        else modi(rc,mid+1,r,x,v);
        up(o);
    }
    int ask1(int o,int l,int r,int x1,int x2){
        if(x1<=l&&r<=x2) return mxd[o];
        int re=-1e9;
        if(x1<=mid) re=Max(re,ask1(lc,l,mid,x1,x2));
        if(x2>mid) re=Max(re,ask1(rc,mid+1,r,x1,x2));
        return re;
    }
    int ask2(int o,int l,int r,int x1,int x2){
        if(x1<=l&&r<=x2) return sum[o];
        int re=0;
        if(x1<=mid) re+=ask2(lc,l,mid,x1,x2);
        if(x2>mid) re+=ask2(rc,mid+1,r,x1,x2);
        return re;
    }
    void dfs1(int x,int Fa){
        fa[x]=Fa; siz[x]=1;
        for(int i=hd[x];i;i=nxt[i]){
            int to=poi[i];
            if(to==Fa) continue;
            dfs1(to,x);
            if(siz[to]>siz[bgs[x]]) bgs[x]=to;
            siz[x]+=siz[to];
        }
    }
    void dfs2(int x,int tp){
        tmp[id[x]=++ID]=val[x]; Top[x]=tp;
        if(bgs[x]) dfs2(bgs[x],tp);
        for(int i=hd[x];i;i=nxt[i]){
            int to=poi[i];
            if(to==fa[x]||to==bgs[x]) continue;
            dfs2(to,to);
        }
    }
    int Amax(int x,int y){
        int re=-1e9;
        for(;Top[x]!=Top[y];x=fa[Top[x]]){
            if(id[Top[x]]<id[Top[y]]) Swap(x,y);
            re=Max(re,ask1(1,1,n,id[Top[x]],id[x]));
        }if(id[x]>id[y]) Swap(x,y);
        return Max(re,ask1(1,1,n,id[x],id[y]));
    }
    int Asum(int x,int y){
        int re=0;
        for(;Top[x]!=Top[y];x=fa[Top[x]]){
            if(id[Top[x]]<id[Top[y]]) Swap(x,y);
            re+=ask2(1,1,n,id[Top[x]],id[x]);
        }if(id[x]>id[y]) Swap(x,y);
        return re+ask2(1,1,n,id[x],id[y]);
    }
    int main(){
        scanf("%d",&n); int q1,q2; char opt[9];
        for(int i=1;i<n;++i)
            scanf("%d%d",&q1,&q2),adde(q1,q2),adde(q2,q1);
        for(int i=1;i<=n;++i) scanf("%d",&val[i]);
        dfs1(1,0); dfs2(1,1);build(1,1,n);
        scanf("%d",&Q);
        while(Q--){
            scanf("%s%d%d",opt,&q1,&q2);
            if(opt[1]=='H') modi(1,1,n,id[q1],q2);
            else if(opt[1]=='M') printf("%d
    ",Amax(q1,q2));
            else if(opt[1]=='S') printf("%d
    ",Asum(q1,q2));
        }return 0;
    }
  • 相关阅读:
    周末毒鸡汤时间
    MySQL 8.0发布,你熟悉又陌生的Hash Join?
    你可能需要的Kafka面试题与答案整理
    流程控制结构
    视图
    事务
    常用约束
    sql99语法的连接查询
    数据类型
    数据操作语句(DML)
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/10561295.html
Copyright © 2011-2022 走看看