A simple problem with integers
Time Limit: 5000MS |
|
Memory Limit: 131072K |
Total Submissions: 97217 |
|
Accepted: 30358 |
Case Time Limit: 2000MS |
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 numbersNandQ. 1≤N,Q≤100000.
The second line containsNNumbers, the initial values ofA1,A2, ... ,AN . -1000000000≤Ai ≤1000000000.
Each of the nextQLines represents an operation.
"Ca b C"Means addingCTo each ofaa ,aa +1, ... ,Ab . -10000≤C≤10000.
"Qa b"means querying the sum ofaa ,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 Yi examines the range update of the tree array instead of the single point update, and the single point update will time out; The tree array is inherently used to dynamically maintain the array prefix and is characterized by updating the value of an element each 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 (s, T, D) to put the interval a[s] ... A[T] All increase d, we introduce an array of delta[i], which means
A[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 within the interval, and the original of the array a
Value is stored in the array org, and delta[i] contributes a value of delta[i]* (x+1-i) to sum[x], 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
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.
#include <iostream>#include<stdio.h>#include<string.h>#defineN 100010#definell Long Longusing namespaceStd;ll C1[n];//C1[i] means i~n co-increase c1[i]ll C2[n];//C2[i] means i~n altogether increased c1[i]*i=c2[i]ll Ans[n];//the stored prefixes andll N,m;stringOp;ll Lowbit (ll x) {returnx& (-x);}voidUpdate (LL x,ll VAL,LL *c) { while(x<=N) {c[x]+=Val; X+=lowbit (x); }}ll getsum (ll x,ll*c) {ll S=0; while(x>0) {s+=C[x]; X-=lowbit (x); } returns;}intMain () {Freopen ("C:\\users\\acer\\desktop\\in.txt","R", stdin); while(SCANF ("%lld%lld", &n,&m)! =EOF) {memset (c1,0,sizeofC1); memset (C2,0,sizeofC2); memset (ans,0,sizeofans); for(intI=1; i<=n;i++) {scanf ("%lld",&Ans[i]); Ans[i]+=ans[i-1]; } getchar (); for(intI=1; i<=m;i++) {cin>>op; if(op=="C") {ll s1,s2,s3; scanf ("%lld%lld%lld",&s1,&s2,&S3); Update (S1,S3,C1);//C1~n together increased the S3Update (s2+1,-S3,C1);//The previous operation has increased the s2~n by more S3 so this step is to subtractUpdate (s1,s1*s3,c2); Update (S2+1,-(s2+1)*s3,c2); } Else if(op=="Q") {ll s1,s2; scanf ("%lld%lld",&s1,&S2); LL cur=ans[s2]-ans[s1-1];//first equals the base value of the S1~s2 interval.Cur+=getsum (S2,C1) * (s2+1)-getsum (S2,C2);//the effect of 0~s2 on prefixes andCur-=getsum (s1-1, C1) * (S1)-getsum (s1-1, C2);//the effect of 0~s1 on prefixes andprintf"%lld\n", cur); } } //for (int i=1;i<=n;i++)//cout<<getsum (i) << ""; //cout<<endl; }}
POJ 3468 A simple problem with integers (tree array interval update)