好长啊,记不住。
链接:https://www.nowcoder.com/acm/contest/77/H
来源:牛客网
题目描述
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.
输入描述:
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.1
The second line contains N numbers, the initial values of A
, A2
, ... , AN
. -1000000000 ≤ Ai
≤ 1000000000.a
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of A
, Aa+1
, ... , Ab
. -10000 ≤ c ≤ 10000.a
"Q a b" means querying the sum of A
, Aa+1
, ... , Ab
.
输出描述:
You need to answer all Q commands in order. One answer in a line.
示例1
输入
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
输出
4 55 9 15
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const int maxn = 1e5+6; ll n,a[maxn],m; struct node { int l,r; ll sum,lazy; void update(ll x) { sum += (r-l+1)*x; lazy += x; } }tree[maxn*4]; void push_up(int x) { tree[x].sum = tree[x<<1].sum+tree[x<<1|1].sum; } void push_down(int x) { ll lazyval = tree[x].lazy; if(lazyval) { tree[x<<1].update(lazyval); tree[x<<1|1].update(lazyval); tree[x].lazy = 0; } } void build(int x,int l,int r) { tree[x].l = l,tree[x].r = r; tree[x].sum = tree[x].lazy = 0; if(l == r) { tree[x].sum = a[l]; } else { int mid = (l+r)/2; build(x<<1,l,mid); build(x<<1|1,mid+1,r); push_up(x); } } void update(int x,int l,int r,ll val) //x是根节点 { int L = tree[x].l; int R = tree[x].r; if(l <= L&&R <= r) { tree[x].update(val); } else { push_down(x); int mid = (L+R)/2; if(mid >= l) update(x<<1,l,r,val); if(r > mid) update(x<<1|1,l,r,val); //注意此处的小于号,不是小于等于,写错会出错 push_up(x); } } ll query(int x,int l,int r) { int L = tree[x].l; int R = tree[x].r; if(l <= L&&R <= r) return tree[x].sum; else { push_down(x); ll ans = 0; int mid = (L+R)/2; if(mid >= l) ans += query(x<<1,l,r); if(r > mid) ans += query(x<<1|1,l,r); push_up(x); return ans; } } int main() { scanf("%d%d",&n,&m); for(int i=1;i <= n;i++) { scanf("%d",&a[i]); } build(1,1,n); while(m--) { char s[2]; int l,r,w; scanf("%s%d%d",s,&l,&r); if(s[0] == 'C') { scanf("%d",&w); update(1,l,r,w); } else { printf("%lld ",query(1,l,r)); } } return 0; } /*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*/
区间加,查询和。