专题二树形结构 J - A Simple Problem with Integers
- 题目
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.
InputThe first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
Output
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.You need to answer all Q commands in order. One answer in a line.
SampleInputcopy Outputcopy 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
The sums may exceed the range of 32-bit integers. - 思路
线段树模板题,模板得不能再模板了,甚至oiwiki上面都有现成的
就是涉及到字母的输入相当麻烦,scanf好像不能先读一个字符再决定下一步操作,最后用的cin - 代码
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<algorithm> using namespace std; long long d[1000000],b[1000000],a[1000005];//区间值,懒惰标记,原始值 long long n,q; void build(long long s, long long t, long long p) { if (s == t) { d[p] = a[s]; return; } long long m = s + ((t - s) >> 1); build(s, m, p * 2), build(m + 1, t, p * 2 + 1); d[p] = d[p * 2] + d[(p * 2) + 1]; } void update(long long l, long long r, long long c, long long s, long long t, long long p) { if (l <= s && t <= r) { d[p] += (t - s + 1) * c, b[p] += c; return; } long long m = s + ((t - s) >> 1); if (b[p] && s != t) { d[p * 2] += b[p] * (m - s + 1), d[p * 2 + 1] += b[p] * (t - m); b[p * 2] += b[p], b[p * 2 + 1] += b[p]; b[p] = 0; } if (l <= m) update(l, r, c, s, m, p * 2); if (r > m) update(l, r, c, m + 1, t, p * 2 + 1); d[p] = d[p * 2] + d[p * 2 + 1]; } long long getsum(long long l, long long r, long long s, long long t, long long p) { if (l <= s && t <= r) return d[p]; long long m = s + ((t - s) >> 1); if (b[p]) { d[p * 2] += b[p] * (m - s + 1), d[p * 2 + 1] += b[p] * (t - m); b[p * 2] += b[p], b[p * 2 + 1] += b[p]; b[p] = 0; } long long sum = 0; if (l <= m) sum = getsum(l, r, s, m, p * 2); if (r > m) sum += getsum(l, r, m + 1, t, p * 2 + 1); return sum; } int main() { while(scanf("%lld%lld",&n,&q)!=EOF) { memset(d,0,sizeof(d)); memset(b,0,sizeof(b)); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); } build(1,n,1); char cc; long long x,y,z; while (q--) { cin >> cc >> x >> y; if (cc == 'Q') cout << getsum(x, y, 1, n, 1) <<endl; else cin >> z, update(x, y, z, 1, n, 1); } } }