Description
You have N integers, a1, a2, ..., an. You need to deal with both kinds of operations. One type of operation is to add some given number to each number in a given interval. The other are to ask for the sum of numbers in a given interval.
Input
The first line contains the 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
2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4
Sample Output
455915
Hint
The sums may exceed the range of 32-bit integers.
Source
POJ monthly--2007.11.25, Yang YiPositive Solution: Tree Array (interval modification, interval query)Problem Solving Report:naked question. Reference blog: http://blog.csdn.net/longshuai0821/article/details/7855519first, look at the update operation (s, T, D) to put the interval a[s] ... A[T] All increase d, we introduce an array of delta[i], which meansA[i] ... A[n] The common increment, n is the size of the array. Then the update operation can be converted to
1) make delta[s] = Delta[s] + D, mean will a[s] ... A[n] Increase d at the same time, but this a[t+1] ... A[n] Added D, so
2) delta[t+1] = delta[t+1]-D, which means a[t+1] ... A[n] simultaneously minus D
Then look at the query operation queries (s, t), beg A[s] ... A[t] of the interval and, converted to the prefix and, set sum[i] = A[1]+...+a[i], then
A[S]+...+A[T] = sum[t]-sum[s-1],
So what about prefixes and sum[x]? It consists of two parts, one is the original sum of the array, and the other is the cumulative increment in the interval, and the original value of array A is saved in the array org.
and Delta[i] contribution value to Sum[x] is delta[i]* (x+1-i), then
SUM[X] = Org[1]+...+org[x] + delta[1]*x + delta[2]* (x-1) + delta[3]* (x-2) +...+delta[x]*1
= Org[1]+...+org[x] + segma (delta[i]* (x+1-i))
= Segma (Org[i]) + (x+1) *segma (Delta[i])-Segma (Delta[i]*i), 1 <= i <= x
=Segma (org[i]-delta[i]*i)+ (x+1) *delta[i], i<=1<=x
This is actually three array org[i], delta[i] and delta[i]*i prefix and, org[i] prefix and remain unchanged, can be obtained beforehand, delta[i] and delta[i]*i prefix and is constantly changing, can be maintained with two tree-like array.
1 //It's made by jump~2#include <iostream>3#include <cstdlib>4#include <cstring>5#include <cstdio>6#include <cmath>7#include <algorithm>8#include <ctime>9#include <vector>Ten#include <queue> One#include <map> A#include <Set> - using namespacestd; -typedefLong LongLL; the Const intMAXN =100011; - intn,m; - intA[MAXN]; - LL Sum[maxn],c1[maxn],c2[maxn],ans; + Charch[ A]; - +InlineintGetint () A { at intw=0, q=0;CharC=GetChar (); - while((c<'0'|| C>'9') && c!='-') C=getchar ();if(c=='-') q=1, c=GetChar (); - while(c>='0'&& c<='9') w=w*Ten+c-'0', C=getchar ();returnQ? -w:w; - } - -InlinevoidAdd (LL x,ll val) { inLL cun=x; - while(x<=N) { toC1[x]+=val; c2[x]+=val*Cun; +x+=x& (-x); - } the } * $ Inline ll query (ll x) {Panax NotoginsengLL total=0; LL cun=x; - while(x>0) { thetotal+=c1[x]* (cun+1)-C2[x]; +x-=x& (-x); A } the returnTotal ; + } - $ Inline ll Count (ll L,ll R) { $ returnQuery (R)-query (l1); - } - theInlinevoidWork () { -N=getint (); M=getint (); for(intI=1; i<=n;i++) A[i]=getint (), sum[i]=sum[i-1]+A[i];Wuyi intL,r; LL Val; the while(m--) { -scanf"%s", CH); Wu if(ch[0]=='C') { -L=getint (); R=getint (); Val=getint (); AboutAdd (L,val); Add (r+1,-val); $}Else{ -L=getint (); R=getint (); -ans=sum[r]-sum[l-1]; ans+=count (l,r); -printf"%lld\n", ans); A } + } the } - $ intMain () the { the Work (); the return 0; the}
POJ3468 A simple problem with integers