• bzoj4034[HAOI2015]T2


    bzoj4034[HAOI2015]T2

    题意:

    N点树,以点 1 为根,且树点有边权。三种操作:把某个节点点权增加 a 、某个节点为根的子树中所有点的点权都增加 a 、询问某个节点到根的路径中所有点的点权和。

    题解:

    本题链剖可过。第二个操作只要每次在构造链的时候找到子树中在链中位置最大的节点,然后区间修改就行。听说正解是DFS序,不过我不会。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define inc(i,j,k) for(int i=j;i<=k;i++)
     5 #define maxn 200000
     6 #define ll long long
     7 using namespace std;
     8 
     9 struct e{int t,n;}; e es[maxn]; int ess,g[maxn];
    10 void pe(int f,int t){es[++ess]=(e){t,g[f]}; g[f]=ess; es[++ess]=(e){f,g[t]}; g[t]=ess;}
    11 int l[maxn*4],r[maxn*4],ch[maxn*4][2],fa[maxn],dep[maxn],pos[maxn],top[maxn],sz[maxn],sgs,mx[maxn];
    12 ll v[maxn][2],sm[maxn*4],tg[maxn*4];
    13 void dfs(int x){
    14     sz[x]=1; for(int i=g[x];i;i=es[i].n)if(es[i].t!=fa[x]){
    15         fa[es[i].t]=x; dep[es[i].t]=dep[x]+1; dfs(es[i].t); sz[x]+=sz[es[i].t];
    16     }
    17 }
    18 void buildchain(int x,int ps){
    19     pos[x]=mx[x]=++sgs; v[sgs][1]=v[x][0]; top[x]=ps; int mx1=0,mx2=0;
    20     for(int i=g[x];i;i=es[i].n)if(es[i].t!=fa[x]&&mx2<sz[es[i].t])mx2=sz[es[i].t],mx1=es[i].t;
    21     if(mx1)buildchain(mx1,ps),mx[x]=max(mx[x],mx[mx1]);
    22     for(int i=g[x];i;i=es[i].n)if(es[i].t!=fa[x]&&es[i].t!=mx1)
    23         buildchain(es[i].t,es[i].t),mx[x]=max(mx[x],mx[es[i].t]);
    24 }
    25 void pushdown(int x){
    26     if(x&&tg[x]){
    27         int lc=ch[x][0],rc=ch[x][1];
    28         if(lc)sm[lc]+=(r[lc]-l[lc]+1)*tg[x],tg[lc]+=tg[x];
    29         if(rc)sm[rc]+=(r[rc]-l[rc]+1)*tg[x],tg[rc]+=tg[x];
    30         tg[x]=0;
    31     }
    32 }
    33 void build(int x,int L,int R){
    34     if(L==R)sm[x]=v[L][1],ch[x][0]=ch[x][1]=0,l[x]=r[x]=L;else{
    35         ch[x][0]=x<<1,l[x]=L,ch[x][1]=x<<1|1,r[x]=R; int M=(L+R)>>1;
    36         build(ch[x][0],L,M); build(ch[x][1],M+1,R); sm[x]=sm[ch[x][0]]+sm[ch[x][1]];
    37     }
    38 }
    39 ll query(int x,int L,int R){
    40     pushdown(x);
    41     if(L<=l[x]&&r[x]<=R)return sm[x];else{
    42         ll q=0;int M=(l[x]+r[x])>>1; if(L<=M)q+=query(ch[x][0],L,R); if(M<R)q+=query(ch[x][1],L,R);
    43         return q;
    44     }
    45 }
    46 void add(int x,int L,int R,ll val){
    47     pushdown(x);
    48     if(L<=l[x]&&r[x]<=R)tg[x]+=val,sm[x]+=(r[x]-l[x]+1)*val;else{
    49         int M=(l[x]+r[x])>>1; if(L<=M)add(ch[x][0],L,R,val); if(M<R)add(ch[x][1],L,R,val);
    50         sm[x]=sm[ch[x][0]]+sm[ch[x][1]];
    51     }
    52 }
    53 inline ll querysum(int x){ll q=0; while(x)q+=query(1,pos[top[x]],pos[x]),x=fa[top[x]]; return q;}
    54 void init1(){ess=0; memset(g,0,sizeof(g));}
    55 void init2(){dep[1]=fa[1]=0; dfs(1); sgs=0; buildchain(1,1); build(1,1,sgs);}
    56 int n,m;
    57 int main(){
    58     //freopen("test.txt","r",stdin);
    59     scanf("%d%d",&n,&m); inc(i,1,n)scanf("%lld",&v[i][0]); init1();
    60     inc(i,1,n-1){int a,b; scanf("%d%d",&a,&b); pe(a,b);} init2();
    61     inc(i,1,m){
    62         int opt,x;ll y; scanf("%d%d",&opt,&x);
    63         if(opt==1)scanf("%lld",&y),add(1,pos[x],pos[x],y);
    64         if(opt==2)scanf("%lld",&y),add(1,pos[x],mx[x],y);
    65         if(opt==3)printf("%lld
    ",querysum(x));
    66     }
    67     return 0;
    68 }

    20160425

  • 相关阅读:
    Python 学习笔记(七)Python字符串(三)
    Python 学习笔记(七)Python字符串(二)
    Python 学习笔记(六)Python第一个程序
    Python 学习笔记(五)常用函数
    Python 学习笔记(四)数字(二)
    行为型模式之责任链模式
    python_frm组件
    django之models学习总结
    HTTP协议
    事件委托
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5689579.html
Copyright © 2020-2023  润新知