zoukankan      html  css  js  c++  java
  • DFS序+线段树(bzoj 4034)

    题目就不多说了。
    本题目,可以用dfs序+线段树做:题目给定了一棵树,树上节点告诉了权值。我们可以先将这棵树进行dfs将一棵树变成线性结构:如图

    变成这样后,然后就可以用线段树。
    • 操作1:也就是将某两个点+a;
    • 操作2:区间更新
    • 操作3:查询起始区间到某点的和
    我们建线段树,需要统计 +,- 抵消后的个数,因为要知道该区间的和,需要知道+a;
    简单插线问线。
    代码---参考下面链接吧或者我的
    友情提示:注意爆int,计算的时候注意是否超int范围;所以wa了好多次。。。
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cctype>
      4 #include <cmath>
      5 #include <set>
      6 #include <map>
      7 #include <list>
      8 #include <queue>
      9 #include <deque>
     10 #include <stack>
     11 #include <string>
     12 #include <vector>
     13 #include <iostream>
     14 #include <algorithm>
     15 #include <stdlib.h>
     16 #include <time.h>
     17 using namespace std;
     18 typedef long long LL;
     19 const int INF=2e9+1e8;
     20 
     21 const int MOD=1e9+7;
     22 const double eps=0.0000000001;
     23 void fre()
     24 {
     25     freopen("test.in","r",stdin);
     26     freopen("test.out","w",stdout);
     27 }
     28 #define MSET(a,b) memset(a,b,sizeof(a))
     29 
     30 const int maxn=1e6+10;
     31 void zpsb(int x)
     32 {
     33     if(x>=0&&x<maxn) return ;
     34     while(1);
     35 }
     36 struct Edge 
     37 {
     38     int t,next;
     39 }edge[maxn];
     40 int sz,first[maxn],Treeval[maxn];
     41 void addedge(int s,int t)
     42 {
     43     edge[sz].t=t,edge[sz].next=first[s];
     44     first[s]=sz++;
     45 }
     46 int in[maxn],out[maxn];
     47 int reid[maxn],io[maxn],tot;
     48 void dfs(int x,int pre)
     49 {
     50     reid[in[x]=tot]=Treeval[x];
     51     io[tot++]=1;
     52     for(int i=first[x];i!=-1;i=edge[i].next)
     53     {
     54         int t=edge[i].t;
     55         if(t==pre) continue;
     56         dfs(t,x);
     57     }
     58     reid[out[x]=tot]=-Treeval[x];
     59     io[tot++]=-1;
     60 }
     61 
     62 
     63 struct SegTree 
     64 {
     65     struct Node 
     66     {
     67         int l,r,flag;
     68         LL lazy,sum;
     69     }T[maxn*4];
     70     void build(int i,int l,int r)
     71     {
     72         T[i].l=l,T[i].r=r;
     73         T[i].lazy=T[i].flag=0;
     74         if(l==r) 
     75         {
     76             T[i].sum=reid[r];
     77             T[i].flag=io[r];
     78             return ;
     79         }
     80         int mid=(l+r)>>1;
     81         build(i<<1,l,mid),build(i<<1|1,mid+1,r);
     82         T[i].sum=T[i<<1].sum+T[i<<1|1].sum;
     83         T[i].flag=T[i<<1].flag+T[i<<1|1].flag;
     84     }
     85     void pushdown(int i)
     86     {
     87         if(T[i].lazy)
     88         {
     89             T[i<<1].sum+=T[i].lazy*T[i<<1].flag;
     90             T[i<<1|1].sum+=T[i].lazy*T[i<<1|1].flag;
     91             T[i<<1].lazy+=T[i].lazy,T[i<<1|1].lazy+=T[i].lazy;
     92             T[i].lazy=0;
     93         }
     94     }
     95     void update(int i,int l,int r,LL k)
     96     {
     97         zpsb(i);
     98         if(T[i].l==l&&T[i].r==r)
     99         {
    100             T[i].sum+=T[i].flag*k;
    101             T[i].lazy+=k;
    102             return ;
    103         }
    104         pushdown(i);
    105         int mid=(T[i].l+T[i].r)>>1;
    106         if(r<=mid) update(i<<1,l,r,k);
    107         else if(l>mid) update(i<<1|1,l,r,k);
    108         else update(i<<1,l,mid,k),update(i<<1|1,mid+1,r,k);
    109         T[i].sum=T[i<<1].sum+T[i<<1|1].sum;
    110     }
    111     LL query(int i,int l,int r)
    112     {
    113         if(T[i].l==l&&T[i].r==r) return T[i].sum;
    114         pushdown(i);
    115         int mid=(T[i].l+T[i].r)>>1;
    116         if(r<=mid) return query(i<<1,l,r);
    117         else if(l>mid) return query(i<<1|1,l,r);
    118         else return query(i<<1,l,mid)+query(i<<1|1,mid+1,r);
    119     }
    120 }wa;
    121 int main()
    122 {
    123     int n,m;
    124     MSET(first,-1);
    125     sz=0;
    126     scanf("%d%d",&n,&m);
    127     for(int i=1;i<=n;i++)
    128         scanf("%d",&Treeval[i]);
    129     for(int i=2;i<=n;i++)
    130     {
    131         int x,y;
    132         scanf("%d%d",&x,&y);
    133         addedge(x,y);
    134         addedge(y,x);
    135     }
    136     tot=1;
    137     dfs(1,1);
    138     // for(int i=1;i<=n;i++)
    139     // {
    140     //     printf("x=%d %d %d
    ",i,in[i],out[i]);
    141     // }
    142     // for(int i=1;i<=2*n;i++)
    143     // {
    144     //     printf("id=%d val=%d
    ",i,reid[i]);
    145     // }
    146     wa.build(1,1,2*n);
    147     while(m--)
    148     {
    149         int opt;
    150         scanf("%d",&opt);
    151         if(opt==1)
    152         {
    153             int x,a;
    154             scanf("%d%d",&x,&a);
    155             wa.update(1,in[x],in[x],(LL)a);
    156             wa.update(1,out[x],out[x],(LL)a);
    157         }
    158         else if(opt==2)
    159         {
    160             int x,a;
    161             scanf("%d%d",&x,&a);
    162             wa.update(1,in[x],out[x],(LL)a);
    163         }
    164         else 
    165         {
    166             int x;
    167             scanf("%d",&x);
    168             printf("%lld
    ",wa.query(1,1,in[x]));
    169         }
    170     }
    171 }
    172 
    173 
    174 /**************************************************/
    175 /**             Copyright Notice                 **/
    176 /**  writer: wurong                              **/
    177 /**  school: nyist                               **/
    178 /**  blog  : http://blog.csdn.net/wr_technology  **/
    179 /**************************************************/


  • 相关阅读:
    转载 centos7安装kafka_2.11-1.0.0 新手入门(集群)
    Kafka得介绍与单节点部署
    MVC Areas
    Session如何保存在sql数据库中
    AsposeCell特定格式表格
    DataTable数据修改,换列
    A1095 Cars on Campus (30 分)
    A1075 PAT Judge (25 分)
    A1016 Phone Bills (25 分)
    A1082 Read Number in Chinese (25 分)
  • 原文地址:https://www.cnblogs.com/coded-ream/p/7207915.html
Copyright © 2011-2022 走看看