• 数据结构(树链剖分):BZOJ 4034: [HAOI2015]T2


    Description

      有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个

    操作,分为三种:
      操作 1 :把某个节点 x 的点权增加 a 。
      操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
      操作 3 :询问某个节点 x 到根的路径中所有点的点权和。
     

    Input

      第一行包含两个整数 N, M 。表示点数和操作数。

      接下来一行 N 个整数,表示树中节点的初始权值。
      接下来 N-1 行每行三个正整数 fr, to , 表示该树中存在一条边 (fr, to) 。
      再接下来 M 行,每行分别表示一次操作。其中第一个数表示该操
      作的种类( 1-3 ) ,之后接这个操作的参数( x 或者 x a ) 。
     

    Output

       对于每个询问操作,输出该询问的答案。答案之间用换行隔开。

     

    Sample Input

    5 5
    1 2 3 4 5
    1 2
    1 4
    2 3
    2 5
    3 3
    1 2 1
    3 5
    2 1 2
    3 3

    Sample Output

    6
    9
    13

    HINT

       对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不

    会超过 10^6 。
     
      
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <cstdlib>
      5 using namespace std;
      6 const int maxn=100010;
      7 int cnt,fir[maxn],to[maxn<<1],nxt[maxn<<1],n,m;
      8 void addedge(int a,int b){
      9     nxt[++cnt]=fir[a];to[cnt]=b;fir[a]=cnt;
     10 }
     11 long long key[maxn],tr[maxn<<2],add[maxn<<2];
     12 int ID[maxn],fa[maxn],top[maxn],end[maxn],sz[maxn],son[maxn];
     13 void Push_up(int x){
     14     tr[x]=tr[x<<1]+tr[x<<1|1];
     15 }
     16 void Add(int x,int l,int r,long long d){
     17     tr[x]+=(r-l+1)*d;
     18     add[x]+=d;
     19 }
     20 void Push_down(int x,int l,int r){
     21     if(add[x]){
     22         int mid=(l+r)>>1;
     23         Add(x<<1,l,mid,add[x]);
     24         Add(x<<1|1,mid+1,r,add[x]);
     25         add[x]=0;
     26     }
     27 }
     28 void Updata(int node,int l,int r,int a,int b,long long d){
     29     if(l>=a&&r<=b){
     30         Add(node,l,r,d);
     31         return;
     32     }
     33     Push_down(node,l,r);
     34     int mid=(l+r)>>1;
     35     if(mid>=a)Updata(node<<1,l,mid,a,b,d);
     36     if(mid<b) Updata(node<<1|1,mid+1,r,a,b,d);
     37     Push_up(node);
     38 }
     39 long long Query(int node,int l,int r,int a,int b){
     40     if(l>=a&&r<=b)return tr[node];
     41     Push_down(node,l,r);
     42     int mid=(l+r)>>1;
     43     long long ret=0;
     44     if(mid>=a)ret=Query(node<<1,l,mid,a,b);
     45     if(mid<b) ret+=Query(node<<1|1,mid+1,r,a,b);
     46     return ret;
     47 }
     48 void DFS(int x){
     49     sz[x]=1;
     50     for(int i=fir[x];i;i=nxt[i]){
     51         if(to[i]==fa[x])continue;
     52         fa[to[i]]=x;
     53         DFS(to[i]);
     54         sz[x]+=sz[to[i]];
     55         son[x]=sz[son[x]]<sz[to[i]]?to[i]:son[x];
     56     }
     57 }
     58 long long Solve(int y){
     59     long long ret=0;
     60     while(y){
     61         ret+=Query(1,1,n,ID[top[y]],ID[y]);
     62         y=fa[top[y]];
     63     }    
     64     return ret;
     65 }    
     66 int cont;
     67 void DFS2(int x,int tp){
     68     ID[x]=++cont;top[x]=tp;
     69     if(son[x])DFS2(son[x],tp);
     70     for(int i=fir[x];i;i=nxt[i])
     71         if(to[i]!=fa[x]&&to[i]!=son[x])
     72             DFS2(to[i],to[i]);
     73     end[x]=cont;        
     74 }    
     75 int main(){
     76     freopen("t2.in","r",stdin);
     77     freopen("t2.out","w",stdout);
     78     scanf("%d %d",&n,&m);
     79     for(int i=1;i<=n;i++)
     80         scanf("%lld",&key[i]);
     81         
     82     for(int i=1,a,b;i<n;i++){
     83         scanf("%d %d",&a,&b);
     84         addedge(a,b);
     85         addedge(b,a);
     86     }    
     87 
     88     DFS(1);
     89     DFS2(1,1);
     90 
     91     for(int i=1;i<=n;i++)
     92         Updata(1,1,n,ID[i],ID[i],key[i]);
     93     int op,x,a;
     94     while(m--){
     95         scanf("%d",&op);
     96         if(op==1){
     97             scanf("%d%d",&x,&a);
     98             Updata(1,1,n,ID[x],ID[x],a);
     99         }
    100         else if(op==2){
    101             scanf("%d%d",&x,&a);
    102             Updata(1,1,n,ID[x],end[x],a);
    103         }
    104         else{
    105             scanf("%d",&x);
    106             printf("%lld
    ",Solve(x));
    107         }
    108     }
    109     return 0;
    110 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    系统设计5:Google三剑客
    lintcode亚麻九题
    设计模式17:单例模式
    设计模式16:迭代器模式
    设计模式15:组合模式
    476. Number Complement
    561. Array Partition I
    627. Swap Salary
    617. Merge Two Binary Trees
    728. Self Dividing Numbers
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5337024.html
Copyright © 2020-2023  润新知