A simple problem with integers
Time Limit: 5000MS |
|
Memory Limit: 131072K |
|
|
|
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 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 Yi
The problem is to update a certain interval and then query, the idea is even more than the other line tree to be simple, but each time it is written error;
idea is very simple, if each update is traversed to the leaf node, there is no doubt time-out, since it is the interval update, we can first increase the value of the inclusion of this interval in the Father interval, The next time you move to a child node, do something like this, plus the added value stored by the Father node, see Code + Comment:
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include < Algorithm> #include <cmath>using namespace std;const int n=100000+10;int n,m,s[n];struct node{int l,r; Long long n,add;//note the data range;} a[n<<2];void build (int l,int r,int k)//build There is nothing to say; {a[k].l=l,a[k].r=r,a[k].add=0; if (l==r) {a[k].n=s[l]; return; } int mid= (L+R)/2; Build (L,mid,2*k); Build (mid+1,r,2*k+1); A[K].N=A[K*2].N+A[K*2+1].N;} void update (int l,int r,int c,int k) {if (l<=a[k].l&&a[k].r<=r) {a[k].n+= (a[k].r-a[k].l+1) *c;// If the conditions are met, each element of this interval must be added C; A[k].add+=c; Store the added value and update it to the child node the next time the update is done; return; } if (A[k].add)//If the parent node value is still there, the child node is also updated; {a[k*2].add+=a[k].add; A[k*2+1].add+=a[k].add; a[k*2].n+= (a[k*2].r-a[k*2].l+1) *a[k].add; a[k*2+1].n+= (a[k*2+1].r-a[k*2+1].l+1) *a[k].add; A[k].add=0; } int mid= (A[K].L+A[K].R)/2; if (l<=mid) update (L,R,C,2*K); if (r>mid) update (L,R,C,2*K+1); A[K].N=A[K*2].N+A[K*2+1].N, backtracking,}long long query (int l,int r,int k) {if (a[k].l==l&&a[k].r==r) return a[k]. N if (a[k].add) {a[k*2].add+=a[k].add; A[k*2+1].add+=a[k].add; a[k*2].n+= (a[k*2].r-a[k*2].l+1) *a[k].add; a[k*2+1].n+= (a[k*2+1].r-a[k*2+1].l+1) *a[k].add; A[k].add=0; } int mid= (A[K].L+A[K].R)/2; if (l>mid) return query (l,r,2*k+1); if (r<=mid) return query (L,R,2*K); return query (l,mid,2*k) +query (mid+1,r,2*k+1);} int main () {while (~scanf ("%d%d", &n,&m)) {memset (a,0,sizeof (a)); for (int i=1; i<=n; i++) scanf ("%d", &s[i]); Build (1,n,1); while (m--) {int a,b,c; GetChar (); Char O=getchar (); if (o== ' Q ') {scanf ("%d%d", &a,&b); printf ("%i64d\n", Query (a,b,1)); } else {SCANF ("%d%d%d", &a,&b,&c); Update (a,b,c,1); }}} return 0;}
In fact, write to find there is no change, but the key is to update and query the child node when the operation;
poj-3468a simple problem with integers, line number interval update query, code hit countless times or error ~ ~