码迷,mamicode.com
首页 > 其他好文 > 详细

对于在线段树上修改整段区间的理解

时间:2014-08-02 01:47:52      阅读:342      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   art   

第一题

HDU1698http://acm.hdu.edu.cn/showproblem.php?pid=1698

这是在区间上进行整段的修改操作,我们就用to[]数组代表修改的lazy标记

记住在构建树和在change函数中自顶向下更新的时候,一定要注意重新回去更新上层的节点,所以末尾需加上update(cur)

bubuko.com,布布扣
 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 #define N 100005
 5 int sum[4*N],to[4*N];
 6 
 7 void update(int x)
 8 {
 9     sum[x]=sum[x<<1]+sum[x<<1|1];
10 }
11 void build(int cur,int x,int y)
12 {
13     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
14     to[cur]=0;
15     if(x==y){
16         sum[cur]=1;
17         return;
18     }
19     build(ls,x,mid);
20     build(rs,mid+1,y);
21     update(cur);
22 }
23 void pushdown(int cur,int x,int y)
24 {
25     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
26     if(to[cur]!=0){
27         to[ls]=to[rs]=to[cur];
28         sum[ls]=(mid-x+1)*to[cur];
29         sum[rs]=(y-mid)*to[cur];
30         to[cur]=0;
31     }
32 }
33 void change(int cur,int x,int y,int s,int t,int v)
34 {
35     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
36     if(x>=s&&y<=t){
37         sum[cur]=(y-x+1)*v;
38         to[cur]=v;
39         return;
40     }
41     pushdown(cur,x,y);
42     if(mid>=s) change(ls,x,mid,s,t,v);
43     if(mid+1<=t) change(rs,mid+1,y,s,t,v);
44     update(cur);
45 }
46 void query(int cur,int x,int y,int s,int t,int &ans)
47 {
48     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
49     if(x>=s&&y<=t){
50         ans+=sum[cur];
51         return;
52     }
53     pushdown(cur,x,y);
54     if(mid>=s) query(ls,x,mid,s,t,ans);
55     if(mid+1<=t) query(rs,mid+1,y,s,t,ans);
56 }
57 int main()
58 {
59     int T,n,Q,a,b,c,ans;
60     scanf("%d",&T);
61     for(int i=1;i<=T;i++){
62         ans=0;
63         scanf("%d%d",&n,&Q);
64         build(1,1,n);
65         for(int j=0;j<Q;j++){
66             scanf("%d%d%d",&a,&b,&c);
67             change(1,1,n,a,b,c);
68         }
69         query(1,1,n,1,n,ans);
70         printf("Case %d: The total value of the hook is %d.\n",i,ans);
71     }
72     return 0;
73 }
View Code

第二题
POJ3468http://poj.org/problem?id=3468

这是在一段区间上添加值,所以与上题的操作不一样,对于每个相加的数,我们应该也不断将lazy节点累加,类似这种的累加操作,我们总是选择

用add[]数组作为lazy标记

当然这道题特别坑的是因为在累加过程中可以达到10000*100000这样子就超过了int的类型,我们就要用LL来定义sum[],add[]和ans

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 #define N 100005
 6 #define LL long long
 7 int a[N];
 8 LL sum[4*N],add[4*N];
 9 void update(int x)
10 {
11     sum[x]=sum[x<<1]+sum[x<<1|1];
12 }
13 void build(int cur,int x,int y)
14 {
15     add[cur]=0;
16     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
17     if(x==y){
18         sum[cur]=a[x];
19         return;
20     }
21     build(ls,x,mid);
22     build(rs,mid+1,y);
23     update(cur);
24 }
25 void pushdown(int cur,int x,int y)
26 {
27     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
28     if(add[cur]!=0){
29         add[ls]+=add[cur];
30         add[rs]+=add[cur];
31         sum[ls]+=(mid-x+1)*add[cur];
32         sum[rs]+=(y-mid)*add[cur];
33         add[cur]=0;
34     }
35 }
36 void change(int cur,int x,int y,int s,int t,int v)
37 {
38     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
39     if(x>=s&&y<=t){
40         sum[cur]+=(y-x+1)*v;
41         add[cur]+=v;
42         return;
43     }
44     pushdown(cur,x,y);
45     if(mid>=s) change(ls,x,mid,s,t,v);
46     if(mid<t) change(rs,mid+1,y,s,t,v);
47     update(cur);
48 }
49 void query(int cur,int x,int y,int s,int t,LL &ans)
50 {
51     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
52     if(x>=s&&y<=t){
53         ans+=sum[cur];
54         return;
55     }
56     pushdown(cur,x,y);
57     if(mid>=s) query(ls,x,mid,s,t,ans);
58     if(mid<t) query(rs,mid+1,y,s,t,ans);
59 }
60 int main()
61 {
62     int q,n,x,y,z;
63     char c;
64     while(scanf("%d%d",&n,&q)!=EOF){
65         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
66         build(1,1,n);
67         for(int i=1;i<=q;i++){
68             cin>>c;
69             if(c==C){
70                 scanf("%d%d%d",&x,&y,&z);
71                 change(1,1,n,x,y,z);
72             }
73             else{
74                 scanf("%d%d",&x,&y);
75                 LL ans=0;
76                 query(1,1,n,x,y,ans);
77                 printf("%I64d\n",ans);
78             }
79         }
80     }
81     return 0;
82 }
View Code

 

对于在线段树上修改整段区间的理解,布布扣,bubuko.com

对于在线段树上修改整段区间的理解

标签:style   blog   http   color   os   io   for   art   

原文地址:http://www.cnblogs.com/CSU3901130321/p/3886044.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!