POJ 3468 线段树 成段更新 懒惰标记

A Simple Problem with Integers

Time Limit:5000MS   Memory Limit:131072K
Case Time Limit:2000MS

Description

You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000. The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000. Each of the next Q lines represents an operation. "C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000. "Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

Sample Output

4
55
9
15

Hint

The sums may exceed the range of 32-bit integers.
 
题解:本题也是线段树系列的模板题之一,要求的是成段更新+懒惰标记。PS:原题的说明有问题,上面说的“C a b c”中的c的范围其实在int32之外,需要使用long long,否则定是WA,真心坑爹,连WA多次,还是在discuss中看到的原因。
 
稍微讲解下代码中的一些细节: step<<1 与 step<<1|1,意思分别是step*2 和step*+1,具体为什么,可以回去复习一下位运算
 

 

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<cstdio>
  5 #include<algorithm>
  6 #include<cmath>
  7 #include<queue>
  8 #include<map>
  9 
 10 #define N 100010
 11 #define M 15
 12 #define mod 1000000007
 13 #define mod2 100000000
 14 #define ll long long
 15 #define maxi(a,b) (a)>(b)? (a) : (b)
 16 #define mini(a,b) (a)<(b)? (a) : (b)
 17 
 18 using namespace std;
 19 
 20 int n,q;
 21 int x[N];
 22 char ch;
 23 int a,b,c;
 24 
 25 struct node
 26 {
 27     ll mark,sum;
 28 }tree[4*N];
 29 
 30 void update(int l,int r,int i)
 31 {
 32     if(!tree[i].mark) return;
 33     int mid=(l+r)/2;
 34     tree[2*i].sum+=tree[i].mark*(ll)(mid-l+1);
 35     tree[2*i+1].sum+=tree[i].mark*(ll)(r-mid);
 36     tree[2*i].mark+=tree[i].mark;
 37     tree[2*i+1].mark+=tree[i].mark;
 38     tree[i].mark=0;
 39 
 40 }
 41 
 42 ll query(int tl,int tr,int l,int r,int i)
 43 {
 44     if(tl>r || tr<l)
 45         return 0;
 46     if(tl<=l && r<=tr)
 47         return tree[i].sum;
 48     update(l,r,i);
 49     int mid=(l+r)/2;
 50 
 51     return query(tl,tr,l,mid,2*i)+query(tl,tr,mid+1,r,2*i+1);
 52 }
 53 
 54 void addd(int tl,int tr,int l,int r,int i,int val)
 55 {
 56     if(tl>r || tr<l)
 57         return;
 58     if(tl<=l && tr>=r){
 59         tree[i].sum+=val*(ll)(r-l+1);
 60         tree[i].mark+=val;
 61         return;
 62     }
 63     update(l,r,i);
 64     int mid=(l+r)/2;
 65     addd(tl,tr,l,mid,2*i,val);
 66     addd(tl,tr,mid+1,r,2*i+1,val);
 67     tree[i].sum=tree[2*i].sum+tree[2*i+1].sum;
 68 }
 69 
 70 void build_tree(int l,int r,int i)
 71 {
 72     if(l==r){
 73         tree[i].sum=x[l];
 74         return;
 75     }
 76     int mid=(l+r)/2;
 77     build_tree(l,mid,2*i);
 78     build_tree(mid+1,r,2*i+1);
 79     tree[i].sum=tree[2*i].sum+tree[2*i+1].sum;
 80 }
 81 
 82 int main()
 83 {
 84     int i;
 85    // freopen("data.in","r",stdin);
 86     //scanf("%d",&T);
 87     //for(int cnt=1;cnt<=T;cnt++)
 88     //while(T--)
 89     while(scanf("%d%d",&n,&q)!=EOF)
 90     {
 91        // printf(" %d %d \n",n,q);
 92        for(i=1;i<=n;i++) scanf("%d",&x[i]);
 93       // printf(" 1\n");
 94        memset(tree,0,sizeof(tree));
 95        build_tree(1,n,1);
 96 
 97 
 98       //  printf(" 2\n");
 99        getchar();
100        while(q--){
101           //  printf(" 3\n");
102             scanf("%c",&ch);
103           //  printf(" %c\n",ch);
104             if(ch=='C'){
105                 //printf(" 31\n");
106                 scanf("%d%d%d",&a,&b,&c);
107                 getchar();
108                 addd(a,b,1,n,1,c);
109 
110             }
111             else{
112                   //  printf(" 32\n");
113                 scanf("%d%d",&a,&b);
114                 getchar();
115                 ll ans=query(a,b,1,n,1);
116                 printf("%I64d\n",ans);
117             }
118        }
119     }
120 
121     return 0;
122 }

 

posted on 2014-08-17 10:45  njczy2010  阅读(150)  评论(0编辑  收藏  举报