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

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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
线段树的区间更新
添加懒惰标记
*/
#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;
}

  

posted @   Painting、时光  阅读(166)  评论(0编辑  收藏  举报
编辑推荐:
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
阅读排行:
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档
· 软件产品开发中常见的10个问题及处理方法
点击右上角即可分享
微信分享提示