A simple problem with integerstime limit:5000msmemory limit:131072kbthis problem would be judged onPKU. Original id:3468
64-bit integer IO format: %lld Java class name: Main
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, a 2, ..., 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
SourcePOJ monthly--2007.11.25 Problem Solving: Learning the section of the tree-shaped array ... Yes, it's amazing.
Give you a sequence, each time you ask for an interval, or each time you add a number to all the elements of an interval.
The tree array is inherently used to dynamically maintain the array prefix and is characterized by updating the value of one element at a time, querying only the prefix of the array and
But the problem is to ask for an array of an interval and to support the batch update of the values of elements within a range, how to do? As a matter of fact
It is still possible to convert the problem into an array prefix and.
First, look at the update operation $update (S, T, D) $ put the interval $a[s] ... a[t]$ all add $d$, we introduce an array $delta[i]$, which represents
$A [i] ... The common increment of a[n]$, n is the size of the array. Then the update operation can be converted to:
1) make $delta[s] = Delta[s] + d$, which means $a[s] ... a[n]$ also add $d$, but so $a[t+1] ... a[n]$ the $d$, so
2) again $delta[t+1] = delta[t+1]-d$, said Will $a[t+1] ... a[n]$ simultaneous reduction of $d$
Then look at the query operation $query (S, t) $, beg $a[s] ... A[t]$ interval and, converted to 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 within the interval, and the original of the array a
Value is stored in the array org, and $delta[i]$ 's contribution to $sum[x]$ is $delta[i]\times (x+1-i) $, then
\[sum[x] = org[1]+...+org[x] + delta[1]\times x + delta[2]\times (x-1) + delta[3]\times (x-2) +...+delta[x]\times 1\]
\[= Org[1]+...+org[x] + \sum_{i = 1}^{x} (delta[i]\times (x+1-i)) \]
\[sum[x] = \sum_{i = 1}^{x} (Org[i]) + (x+1) \times\sum_{i = 1}^{x} (Delta[i])-\sum_{i = 1}^{x} (delta[i]\times i) \]
can be converted to $\sum_{i=1}^{x} (org[i]-delta[i]*i) + (x+1) *delta[i]$
This is actually three arrays org[i], delta[i] and delta[i]*i prefixes and, org[i] prefixes and remains the same, can be obtained beforehand, delta[i] and
The delta[i]*i prefix and is constantly changing, and can be maintained with two tree arrays.
1#include <cstdio>2#include <cstring>3 4 using namespacestd;5typedefLong LongLL;6 Const intMAXN =100010;7LL s[maxn],c[2][MAXN];8 intn,m;9 voidAdd (LL *c,inti,ll val) {Ten while(I <=N) { OneC[i] + =Val; Ai + = i&-i; - } - } thell sum (ll *c,intI,LL ret =0) { - while(I >0) { -RET + =C[i]; -I-= i&-i; + } - returnret; + } A intMain () { at Charcmd[4]; - LL x, y, Z; - while(~SCANF ("%d%d",&n,&m)) { -Memset (c,0,sizeofc); - for(inti =1; I <= N; ++i) { -scanf"%lld", S +i); inS[i] + = s[i-1]; - } to while(m--) { +scanf"%s", cmd); - if(cmd[0] =='C') { thescanf"%lld%lld%lld",&x,&y,&z); *Add (c[0],x,z); $Add (c[0],y+1,-z);Panax NotoginsengAdd (c[1],x,x*z); -Add (c[1],y+1,-z* (y+1)); the}Else { +scanf"%lld%lld",&x,&y); Aprintf"%lld\n", S[y]-s[x-1] + (y+1) *sum (c[0],y)-SUM (c[1],y)-X*sum (c[0],x-1) + SUM (c[1],x-1)); the } + } - } $ return 0; $}View Code
POJ 3468 A simple problem with integers