zoukankan      html  css  js  c++  java
  • [bzoj4034]树上操作

    dfs序(注意出栈时也要加入),然后对于每一次一个节点的修改,都在左端点上打+x,右端点上打-x,区间修改同理(因此要用线段树且需要维护区间左端点数量-右端点数量)。对于询问操作,就是dfs序上的一段前缀和,用线段树处理即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 #define ll long long
     4 #define maxN 100001
     5 #define L (k<<1)
     6 #define R ((k<<1)+1)
     7 #define mid ((l+r)>>1)
     8 struct ji{
     9     int next,to;
    10 }edge[maxN<<1];
    11 struct node{
    12     ll k,s,lazy;
    13 }f[maxN<<4];
    14 ll E,n,m,x,y,a[maxN],head[maxN],l[maxN],r[maxN];
    15 bool vis[maxN<<1];
    16 void init(){
    17     E=0;
    18     memset(head,-1,sizeof(head));
    19 }
    20 void add(int x,int y){
    21     edge[E].next=head[x];
    22     edge[E].to=y;
    23     head[x]=E++;
    24 }
    25 void up(int k){
    26     f[k].k=f[L].k+f[R].k+f[k].lazy*(f[k].s=f[L].s+f[R].s);
    27 }
    28 void down(int k){
    29     f[L].lazy+=f[k].lazy;
    30     f[L].k+=f[k].lazy*f[L].s;
    31     f[R].lazy+=f[k].lazy; 
    32     f[R].k+=f[k].lazy*f[R].s;
    33     f[k].lazy=0;
    34 }
    35 void update(int k,int l,int r,int x,int y,int z){
    36     if ((r<x)||(l>y))return;
    37     if ((x<=l)&&(r<=y)){
    38         if (l==r)
    39             if (vis[l])f[k].s=1;
    40             else f[k].s=-1;
    41         f[k].k+=f[k].s*z;
    42         f[k].lazy+=z;
    43         return;
    44     }
    45     update(L,l,mid,x,y,z);
    46     update(R,mid+1,r,x,y,z);
    47     up(k);
    48 }
    49 ll query(int k,int l,int r,int x,int y){
    50     if ((l>y)||(r<x))return 0;
    51     if ((x<=l)&&(y>=r))return f[k].k;
    52     down(k);
    53     return query(L,l,mid,x,y)+query(R,mid+1,r,x,y);
    54 }
    55 void dfs(int k,int f){
    56     vis[l[k]=++x]=true;
    57     for(int i=head[k];i!=-1;i=edge[i].next)
    58         if (edge[i].to!=f)dfs(edge[i].to,k);
    59     r[k]=++x;
    60 }
    61 int main(){
    62     int p;
    63     init();
    64     scanf("%lld%lld",&n,&m);
    65     for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    66     for(int i=1;i<n;i++){
    67         scanf("%lld%lld",&x,&y);
    68         add(x,y);
    69         add(y,x);
    70     }
    71     x=0;
    72     dfs(1,0);
    73     for(int i=1;i<=n;i++){
    74         update(1,1,2*n,l[i],l[i],a[i]);
    75         update(1,1,2*n,r[i],r[i],a[i]);
    76     } 
    77     n*=2;
    78     for(int i=1;i<=m;i++){
    79         scanf("%d%lld",&p,&x);
    80         if (p<3)scanf("%lld",&y);
    81         if (p==1){
    82             update(1,1,n,l[x],l[x],y);
    83             update(1,1,n,r[x],r[x],y);
    84         }
    85         if (p==2)update(1,1,n,l[x],r[x],y);
    86         if (p==3)printf("%lld\n",query(1,1,n,1,l[x]));
    87     }
    88 }
    View Code
  • 相关阅读:
    iOS7——UIControlEventTouchDown延迟响应问题
    View.setTag(key,object)异常:The key must be an application-specific resource id.
    为什么阿里巴巴规定禁止超过三张表 join?
    四种常见的系统架构,目前你处于哪个阶段呢?
    JAVA BigDecimal的相加(累加)
    MyBatis中Like语句使用方式
    mybatis传参的几种方式
    英语说话方式思维和汉语说话的区别
    EXTJs前端传值的几种方式
    oracle+MyBatis批量导入sublist
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249921.html
Copyright © 2011-2022 走看看