zoukankan      html  css  js  c++  java
  • 【bzoj4034】[HAOI2015]T2

    siz[v]表示以v为根的子树的节点数

    top[v]表示v所在的重链的顶端节点

    fa[v]表示v的父亲

    pos[v]表示v的父边标号

    mx[v]表示v的子树中边的标号最大的那条边

    参考:http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html

    题意:

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

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

    第一次写树链剖分。。

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 using namespace std;
      8  
      9 typedef long long LL;
     10  
     11 #define N 100010
     12  
     13 int id;
     14 int fa[N],siz[N],top[N];
     15 int head[N],pos[N],mx[N],v[N];
     16 LL sum[N<<2],add[N<<2];
     17  
     18 struct Node
     19 {
     20     int to,next;
     21 }e[N<<1];
     22 int cnt;
     23  
     24 int n,m;
     25 int uu,vv;
     26  
     27 int read()
     28 {
     29     int x=0,f=1;char ch=getchar();
     30     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     31     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     32     return x*f;
     33 }
     34  
     35 void link(int x,int y)
     36 {
     37     e[++cnt]=(Node){y,head[x]};
     38     head[x]=cnt;
     39 }
     40  
     41 void dfs(int x)
     42 {
     43     siz[x]=1;
     44     for (int i=head[x];i;i=e[i].next)
     45         if (e[i].to!=fa[x])
     46         {
     47             fa[e[i].to]=x;
     48             dfs(e[i].to);
     49             siz[x]+=siz[e[i].to];
     50             mx[x]=max(mx[x],mx[e[i].to]);
     51         }
     52 }
     53  
     54 void dfs2(int x,int cha)
     55 {
     56     top[x]=cha;pos[x]=mx[x]=++id;
     57     int k=0;
     58     for(int i=head[x];i;i=e[i].next)
     59         if(e[i].to!=fa[x]&&siz[e[i].to]>siz[k])
     60             k=e[i].to;
     61     if(k)
     62     {
     63         dfs2(k,cha);mx[x]=max(mx[x],mx[k]);
     64     }
     65     for(int i=head[x];i;i=e[i].next)
     66         if(e[i].to!=fa[x]&&e[i].to!=k)
     67         {
     68             dfs2(e[i].to,e[i].to);
     69             mx[x]=max(mx[x],mx[e[i].to]);
     70         }
     71 }
     72  
     73 void pushup(int now)
     74 {
     75     sum[now]=sum[now<<1]+sum[now<<1|1];
     76 }
     77  
     78 void pushdown(int nowl,int nowr,int now)
     79 {
     80     if (nowl==nowr)
     81         return;
     82     int mid=(nowl+nowr)>>1;
     83     LL t=add[now];
     84     add[now]=0;
     85     add[now<<1]+=t;
     86     add[now<<1|1]+=t;
     87     sum[now<<1]+=t*(mid-nowl+1);
     88     sum[now<<1|1]+=t*(nowr-mid);
     89 }
     90  
     91 void update(int nowl,int nowr,int now,int l,int r,LL d)
     92 {
     93     if (add[now])
     94         pushdown(nowl,nowr,now);
     95     if (nowl==l && nowr==r)
     96     {
     97         add[now]+=d;
     98         sum[now]+=(nowr-nowl+1)*d;
     99         return ;
    100     }
    101     int mid=(nowl+nowr)>>1;
    102     if (l<=mid)
    103         update(nowl,mid,now<<1,l,min(r,mid),d);
    104     if (r>mid)
    105         update(mid+1,nowr,now<<1|1,max(l,mid+1),r,d);
    106     pushup(now);
    107 }
    108  
    109 LL query(int nowl,int nowr,int now,int l,int r)
    110 {
    111     if (add[now])
    112         pushdown(nowl,nowr,now);
    113     if (nowl==l && nowr==r)
    114         return sum[now];
    115     int mid=(nowl+nowr)>>1;
    116     LL ans=0;
    117     if (l<=mid)
    118         ans+=query(nowl,mid,now<<1,l,min(mid,r));
    119     if (r>mid)
    120         ans+=query(mid+1,nowr,now<<1|1,max(mid+1,l),r);
    121     return ans;
    122 }
    123  
    124 LL query(int x)
    125 {
    126     LL ans=0;
    127     while (top[x]!=1)
    128     {
    129         ans+=query(1,n,1,pos[top[x]],pos[x]);
    130         x=fa[top[x]];
    131     }
    132     ans+=query(1,n,1,1,pos[x]);
    133     return ans;
    134 }
    135  
    136 int main()
    137 {
    138     n=read(),m=read();
    139     for (int i=1;i<=n;i++)
    140         v[i]=read();
    141     for (int i=1;i<n;i++)
    142     {
    143         uu=read(),vv=read();
    144         link(uu,vv);
    145         link(vv,uu);
    146     }
    147     dfs(1);
    148     dfs2(1,1);
    149     for (int i=1;i<=n;i++)
    150         update(1,n,1,pos[i],pos[i],v[i]);
    151     int askd,x,a;
    152     while (m--)
    153     {
    154         askd=read(),x=read();
    155         if (askd==1)
    156         {
    157             a=read();
    158             update(1,n,1,pos[x],pos[x],a);
    159         }
    160         if (askd==2)
    161         {
    162             a=read();
    163             update(1,n,1,pos[x],mx[x],a);
    164         }
    165         if (askd==3)
    166             printf("%lld
    ",query(x));
    167     }
    168     return 0;
    169 }
  • 相关阅读:
    词法分析程序
    0909关于编译原理
    深度学习中图像检测的评价标准
    【 记忆网络 1 】 Memory Network
    ssm又乱码
    百度地图标注没了
    Fragment与Activity交互(使用Handler)
    在android里用ExpandableListView实现二层和三层列表
    java中outer的使用
    android中使用Http下载文件并保存到本地SD卡
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5328498.html
Copyright © 2011-2022 走看看