A Simple Problem with Integers
Case Time Limit: 2000MS
Description
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
The sums may exceed the range of 32-bit integers.
算法:线段树+延迟标记
#include <iostream> #include <cstdio> using namespace std; const int maxn = 1e5+7; typedef long long ll; struct node { int l, r; ll sum; }tree[maxn << 2]; int n, m; ll arr[maxn]; ll lazy[maxn << 2]; //懒惰数组 void pushup(int root) { tree[root].sum = tree[root << 1].sum + tree[root << 1 | 1].sum; } void build(int root, int l ,int r) { tree[root].l = l; tree[root].r = r; lazy[root] = 0; if(l == r) { tree[root].sum = arr[l]; return; } int mid = (l + r) >> 1; build(root << 1, l, mid); build(root << 1 | 1, mid + 1, r); pushup(root); } void spread(int root) { if(lazy[root]) { //判断延迟标记是否存在 lazy[root << 1] += lazy[root]; //左子树下传延迟标记 lazy[root << 1 | 1] += lazy[root]; //右子树下传延迟标记 tree[root << 1].sum += lazy[root] * (tree[root << 1].r - tree[root << 1].l + 1); //更新左结点信息 tree[root << 1 | 1].sum += lazy[root] * (tree[root << 1 | 1].r - tree[root << 1 | 1].l + 1); //更新右结点信息 lazy[root] = 0; //清除延迟标记 } } void update(int root, int x, int y, ll val) { int l = tree[root].l; int r = tree[root].r; if(x <= l && r <= y) { tree[root].sum += (r - l + 1) * val; lazy[root] += val; //添加延迟标记 return; } spread(root); //下传延迟标记 int mid = (l + r) >> 1; if(x <= mid) { update(root << 1, x, y, val); } if(y > mid) { update(root << 1 | 1, x, y, val); } pushup(root); } ll query(int root, int x, int y) { int l = tree[root].l; int r = tree[root].r; if(x <= l && r <= y) { //完全覆盖 return tree[root].sum; } spread(root); //下传延迟标记 ll res = 0; int mid = (l + r) >> 1; if(x <= mid) { res += query(root << 1, x, y); } if(y > mid) { res += query(root << 1 | 1, x, y); } return res; } int main() { while(~scanf("%d %d", &n, &m)) { for(int i = 1; i <= n; i++) { scanf("%lld", &arr[i]); } build(1, 1, n); while(m--) { char op[5]; int l, r; scanf("%s", op); if(op[0] == 'Q') { scanf("%d %d", &l, &r); printf("%lld ", query(1, l, r)); } else { ll val; scanf("%d %d %lld", &l, &r, &val); update(1, l, r, val); } } } return 0; }