• 【BZOJ】【4034】【HAOI2015】T2


    树链剖分/dfs序


      树上单点修改+子树修改+链查询

      其实用dfs序做也可以……

      其实树链剖分就是一个特殊的dfs序嘛= =所以树链剖分也可以搞子树~(Orz ZYF)

      至于为什么……你看在做剖分的时候不也是dfs下去的?然后只不过是先走重儿子,但本质上也是一个dfs序,所以dfs序能搞的子树操作,链剖也是兹瓷的~

      然后随便水水就过了……

      WA了一发:查询从x到1的权值和的时候,写成了while(top[x]),改成while(x)后就过了……

      1 /**************************************************************
      2     Problem: 4034
      3     User: Tunix
      4     Language: C++
      5     Result: Accepted
      6     Time:2192 ms
      7     Memory:27956 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 4034
     11 #include<vector>
     12 #include<cstdio>
     13 #include<cstring>
     14 #include<cstdlib>
     15 #include<iostream>
     16 #include<algorithm>
     17 #define rep(i,n) for(int i=0;i<n;++i)
     18 #define F(i,j,n) for(int i=j;i<=n;++i)
     19 #define D(i,j,n) for(int i=j;i>=n;--i)
     20 #define pb push_back
     21 using namespace std;
     22 inline int getint(){
     23     int v=0,sign=1; char ch=getchar();
     24     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
     25     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
     26     return v*sign;
     27 }
     28 const int N=2e5+10,INF=~0u>>2;
     29 typedef long long LL;
     30 /******************tamplate*********************/
     31  
     32  
     33 int to[N<<1],nxt[N<<1],head[N],cnt;
     34 void add(int x,int y){
     35     to[++cnt]=y; nxt[cnt]=head[x]; head[x]=cnt;
     36     to[++cnt]=x; nxt[cnt]=head[y]; head[y]=cnt;
     37 }
     38 LL n,m,a[N];
     39 LL sm[N<<2],ad[N<<2];
     40 #define mid (l+r>>1)
     41 #define L (o<<1)
     42 #define R (o<<1|1)
     43 inline void maintain(int o,int l,int r){
     44     sm[o]=sm[L]+sm[R];
     45 }
     46 inline void Push_down(int o,int l,int r){
     47     if (ad[o]) {
     48         ad[L]+=ad[o]; sm[L]+=ad[o]*(mid-l+1);
     49         ad[R]+=ad[o]; sm[R]+=ad[o]*(r-mid);
     50         ad[o]=0;
     51     }
     52 }
     53 void update(int o,int l,int r,int ql,int qr,LL v){
     54     if (ql<=l && qr>=r) sm[o]+=v*(LL)(r-l+1),ad[o]+=v;
     55     else{
     56         Push_down(o,l,r);
     57         if (ql<=mid) update(L,l,mid,ql,qr,v);
     58         if (qr>mid) update(R,mid+1,r,ql,qr,v);
     59         maintain(o,l,r);
     60     }
     61 }
     62 LL query_it(int o,int l,int r,int ql,int qr){
     63     if (ql<=l && qr>=r) return sm[o];
     64     else{
     65         LL ans=0; Push_down(o,l,r);
     66         if (ql<=mid) ans+=query_it(L,l,mid,ql,qr);
     67         if (qr>mid) ans+=query_it(R,mid+1,r,ql,qr);
     68         return ans;
     69     }
     70 }
     71  
     72 int top[N],fa[N],dep[N],tid[N],st[N],ed[N],son[N],size[N];
     73 void dfs(int x){
     74     size[x]=1; son[x]=0;
     75     int mx=0;
     76     for(int i=head[x];i;i=nxt[i])
     77         if (to[i]!=fa[x]){
     78             fa[to[i]]=x;
     79             dep[to[i]]=dep[x]+1;
     80             dfs(to[i]);
     81             size[x]+=size[to[i]];
     82             if (size[to[i]]>mx) mx=size[to[i]],son[x]=to[i];
     83         }
     84 }
     85 int tot;
     86 bool vis[N];
     87 void connect(int x,int f){
     88     vis[x]=1;
     89     top[x]=f;
     90     st[x]=tid[x]=++tot;
     91     if (son[x]) connect(son[x],f);
     92     for(int i=head[x];i;i=nxt[i])
     93         if (!vis[to[i]])
     94             connect(to[i],to[i]);
     95     ed[x]=tot;
     96 }
     97 LL query(int x){
     98     LL ans=0;
     99     while(x){
    100         ans+=query_it(1,1,n,tid[top[x]],tid[x]);
    101         x=fa[top[x]];
    102     }
    103     return ans;
    104 }
    105 int main(){
    106 #ifndef ONLINE_JUDGE
    107     freopen("4034.in","r",stdin);
    108     freopen("4034.out","w",stdout);
    109 #endif
    110     n=getint(); m=getint();
    111     F(i,1,n) a[i]=getint();
    112     F(i,2,n){
    113         int x=getint(),y=getint();
    114         add(x,y);
    115     }
    116     dfs(1);
    117     connect(1,1);
    118     F(i,1,n) update(1,1,n,tid[i],tid[i],a[i]);
    119     int cmd,x,y;
    120     F(i,1,m){
    121         cmd=getint(); x=getint();
    122         if (cmd==1){
    123             y=getint();
    124             update(1,1,n,tid[x],tid[x],y);
    125         }else if (cmd==2){
    126             y=getint();
    127             update(1,1,n,st[x],ed[x],y);
    128         }else{
    129             printf("%lld
    ",query(x));
    130         }
    131     }
    132     return 0;
    133 }
    View Code

    4034: [HAOI2015]T2

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 265  Solved: 113
    [Submit][Status][Discuss]

    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 。

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    排队打饭 sdut 2443【最简单的贪心法应用举例】
    sdut 2445 小学数学
    最终排名 sdut 2446
    sort函数用法
    sdut1598 周游列国【简单模拟题】
    sdut 2441 屠夫与狼
    男生女生分配
    qsort函数详解
    test1.A[【dfs简单题】
    sdut 2449走迷宫【最简单的dfs应用】
  • 原文地址:https://www.cnblogs.com/Tunix/p/4498702.html
Copyright © 2020-2023  润新知