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, A1, A2, ... , 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 A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+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
代码如下:
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 }
以上是关于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 分块