POJ3468 A Simple Problem with Integers —— 线段树 区间修改

Posted h_z_cong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ3468 A Simple Problem with Integers —— 线段树 区间修改相关的知识,希望对你有一定的参考价值。

题目链接:https://vjudge.net/problem/POJ-3468

 

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.

 

 

代码如下:

技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <string>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 const double EPS = 1e-8;
15 const int INF = 2e9;
16 const LL LNF = 2e18;
17 const int MAXN = 1e5+10;
18 
19 LL sum[MAXN*4], addv[MAXN*4];
20 
21 void push_up(int u)
22 {
23     sum[u] = sum[u*2] + sum[u*2+1];
24 }
25 
26 void push_down(int u, int l, int r)
27 {
28     if(addv[u]!=0)
29     {
30         sum[u*2] += 1LL*(r-l+1+1)/2*addv[u];
31         sum[u*2+1] += 1LL*(r-l+1)/2*addv[u];
32         addv[u*2] += addv[u];
33         addv[u*2+1] += addv[u];
34         addv[u] = 0;
35     }
36 }
37 
38 void add(int u, int l, int r, int x, int y, int val)
39 {
40     if(x<=l && r<=y)
41     {
42         addv[u] += val;
43         sum[u] += 1LL*(r-l+1)*val;
44         return;
45     }
46 
47     push_down(u, l, r);
48     int mid = (l+r)/2;
49     if(x<=mid) add(u*2, l, mid, x, y, val);
50     if(y>=mid+1) add(u*2+1, mid+1, r, x, y, val);
51     push_up(u);
52 }
53 
54 LL query(int u, int l, int r, int x, int y)
55 {
56     if(x<=l && r<=y)
57         return sum[u];
58 
59     push_down(u, l, r);
60     LL ret = 0;
61     int mid = (l+r)/2;
62     if(x<=mid) ret += query(u*2, l, mid, x, y);
63     if(y>=mid+1) ret += query(u*2+1, mid+1, r, x, y);
64     return ret;
65 }
66 
67 int main()
68 {
69     int n, m;
70     while(scanf("%d%d", &n, &m)!=EOF)
71     {
72         memset(sum, 0, sizeof(sum));
73         memset(addv, 0, sizeof(addv));
74         char op[2]; int a, b, c;
75         for(int i = 1; i<=n; i++)
76         {
77             scanf("%d", &a);
78             add(1, 1, n, i, i, a);
79         }
80 
81         for(int i = 1; i<=m; i++)
82         {
83             scanf("%s", op);
84             if(op[0]==C)
85             {
86                 scanf("%d%d%d", &a, &b, &c);
87                 add(1, 1, n, a, b, c);
88             }
89             else
90             {
91                 scanf("%d%d", &a, &b);
92                 printf("%d\n", query(1, 1, n, a, b));
93             }
94         }
95     }
96 }
View Code

 





以上是关于POJ3468 A Simple Problem with Integers —— 线段树 区间修改的主要内容,如果未能解决你的问题,请参考以下文章

A Simple Problem with Integers POJ - 3468

POJ - 3468 A Simple Problem with Integers

[poj3468]A Simple Problem with Integers

POJ3468 a simple problem with integers 分块

POJ 3468 A Simple Problem with Integers 树状数组

POJ 3468 A Simple Problem with Integers