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

POJ3468——线段树区间更新——A Simple Problem with Integers

时间:2015-08-01 17:14:06      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:

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 abc" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q ab" 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
/*
线段树的区间更新
添加懒惰标记
*/
#include <cstdio>
#include <algorithm>
using namespace std;

const int MAX = 1000000;
long long  a[MAX];
long long  lazy[MAX];
long long  sum[MAX<<2];

void build(long long  rt, long long  l, long long  r)
{
    sum[rt] = lazy[rt] = 0;
    if(l == r){
        sum[rt] = a[l];
        return ;
    }
    long long  mid = (l + r) /2 ;
    build(rt*2, l, mid);
    build(rt*2+1, mid+1, r);
    sum[rt] = sum[rt*2] + sum[rt*2+1];
}

void down(long long  rt, long long  l, long long  r)
{
  if(lazy[rt]){
      long long  mid = (l + r) / 2;
      lazy[rt*2] += lazy[rt]; lazy[rt*2+1] += lazy[rt];
      sum[rt*2] += lazy[rt]*(mid-l+1);
      sum[rt*2+1] += lazy[rt]*(r-mid);
      lazy[rt] = 0;
  }
}

void update(long long rt, long long  l, long long  r, long long  L, long long  R, long long  y)
{
 if(L <= l && R >= r){
     lazy[rt] += y;
     sum[rt] += y*(r-l+1);
     return;
 }
 down(rt, l, r);
 long long  mid = (l + r) /2 ;
 if(L <= mid) update(rt*2, l , mid, L, R, y);
 if(R > mid) update(rt*2+1, mid+1, r, L, R, y);
 sum[rt] = sum[rt*2] + sum[rt*2+1];
}

long long  query(long long  rt, long long  l, long long  r, long long  L, long long  R)
{
    if(L <= l && R >= r) return sum[rt];
    down(rt, l, r);
    long long  mid = (l + r) / 2;
    long long  ret = 0;
    if(L <= mid) ret += query(rt*2, l , mid, L ,R);
    if(R > mid) ret += query(rt*2+1, mid+1, r, L, R);
    sum[rt]  = sum[rt*2] + sum[rt*2+1];
    return ret;
}

int main()
{
    int n, q;
    long long  x, y,z;
    char s[10];
    while(~scanf("%d%d", &n, &q)){
        for(int i = 1; i <= n ; i++)
            scanf("%I64d", &a[i]);
        build(1, 1, n);
        for(int i = 1; i <= q; i++){
            scanf("%s", s);
            if(s[0] == ‘Q‘){
                scanf("%I64d%I64d", &x, &y);
                printf("%I64d\n", query(1, 1, n, x, y));
            }
            else{
               scanf("%I64d%I64d%I64d", &x, &y, &z);
               update(1, 1, n, x, y, z);
            }
        }
    }
    return 0;
}

  

POJ3468——线段树区间更新——A Simple Problem with Integers

标签:

原文地址:http://www.cnblogs.com/zero-begin/p/4694198.html

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