poj 3468 A Simple Problem with Integers

题意:给你一串数字,对这些数字有两种操作:

                                                         1.Q a b :问数字串从a到b的和。

                                                         2.C a b c :对数字串a到b逐个加上c。

题解:线段树+lazy。

所谓lazy思想我的理解就是对于线段树的更新时仅仅在要更新的区间上标记一下,并不进行实际的更新操作,只有当要询问这一区间的信息时再更新。节省了不必要的更新操作。所以在查询时首先要做的就是查看标记这一段是否需要进行更新操做,然后进行相应的操作。

AC代码:

View Code
 1 #include<cstdio>
 2 #include<iostream>
 3 #define LL long long
 4 using namespace std;
 5 const int maxn=10000000;
 6 LL sum[maxn],add[maxn];
 7 void Build(int l,int r,int pos){
 8     add[pos]=0;
 9     if(l==r){
10         scanf("%lld",&sum[pos]);
11         return;
12     }
13     int mid=(l+r)>>1;
14     Build(l,mid,pos*2);
15     Build(mid+1,r,pos*2+1);
16     sum[pos]=sum[pos*2]+sum[pos*2+1];
17 }
18 void PushDown(int pos,int num){
19     if(add[pos]){
20         add[pos*2]+=add[pos];
21         add[pos*2+1]+=add[pos];
22         sum[pos*2]+=add[pos]*(num-(num>>1));
23         sum[pos*2+1]+=add[pos]*(num>>1);
24         add[pos]=0;
25     }
26 }
27 LL Query(int l,int r,int left,int right,int pos){
28     if(l<=left&&right<=r)return sum[pos];
29     PushDown(pos,right-left+1);
30     int mid=(left+right)>>1;
31     if(r<=mid)return Query(l,r,left,mid,pos*2);
32     if(l>mid)return Query(l,r,mid+1,right,pos*2+1);
33     LL lsum=Query(l,r,left,mid,pos*2);
34     LL rsum=Query(l,r,mid+1,right,pos*2+1);
35     return lsum+rsum;
36 }
37 void Updata(int l,int r,int c,int left,int right,int pos){
38     if(l<=left&&right<=r){
39         add[pos]+=c;
40         sum[pos]+=(LL)(c*(right-left+1));
41         return;
42     }
43     PushDown(pos,right-left+1);
44     int mid=(left+right)>>1;
45     if(r<=mid)Updata(l,r,c,left,mid,pos*2);
46     else if(l>mid)Updata(l,r,c,mid+1,right,pos*2+1);
47     else{
48         Updata(l,r,c,left,mid,pos*2);
49         Updata(l,r,c,mid+1,right,pos*2+1);
50     }
51     sum[pos]=sum[pos*2]+sum[pos*2+1];
52 }
53 int main()
54 {
55     int N,Q,a,b,c;
56     char oper[2];
57     scanf("%d %d",&N,&Q);
58     Build(1,N,1);
59     while(Q--){
60         scanf("%s",oper);
61         if(oper[0]=='Q'){
62             scanf("%d %d",&a,&b);
63             printf("%lld\n",Query(a,b,1,N,1));
64         }
65         else{
66             scanf("%d %d %d",&a,&b,&c);
67             Updata(a,b,c,1,N,1);
68         }
69     }
70     return 0;
71 }

 

posted on 2012-10-12 17:10  Acmer_Roney  阅读(155)  评论(0编辑  收藏  举报

导航