Description
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.
Input
The first line contains two 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
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
Sample Output
4 55 9 15
Hint
The sums may exceed the range of 32-bit integers.
这道题我没做出来
看了一下poj.pdf 的解题思路
他的解题思路太好了,如下;
在增加时,如果要加的区间正好覆盖一个节点,则增加其节点的Inc值,不再往下走,否则要更新nSum(加上本次增量),再将增量往下传。这样更新的复杂度就是O(log(n))在查询时,如果待查区间不是正好覆盖一个节点,就将节点的Inc往下带,然后将Inc代表的所有增量累加到nSum上后将Inc清0,接下来再往下查询。Inc往下带的过程也是区间分解的过程,复杂度也是O(log(n))
一下为我的代码
#include<stdio.h>
#include<iostream>
using namespace std;
int a[101010];
struct ele
{
int left;
int right;
__int64 sum;
__int64 value;
}p[505050];
void build(int L,int R,int step)
{
p[step].left=L;
p[step].right=R;
if(L==R)
{
p[step].sum=a[L];
p[step].value=0;
}
else
{
int Mid=(L+R)/2;
build(L,Mid,2*step);
build(Mid+1,R,2*step+1);
p[step].sum=p[2*step].sum+p[2*step+1].sum;
p[step].value=0;
}
}
__int64 Find(int x,int y,int step)
{
if(p[step].left==x&&p[step].right==y)
return p[step].sum+p[step].value*(y-x+1);
else
{
p[step].sum=p[step].sum+(p[step].right-p[step].left+1)*p[step].value;
p[2*step].value=p[2*step].value+p[step].value;
p[2*step+1].value=p[2*step+1].value+p[step].value;
p[step].value=0;
int Mid=(p[step].left+p[step].right)/2;
if(y<=Mid)
return Find(x,y,2*step);
else
if(x>=Mid+1)
return Find(x,y,2*step+1);
else
return Find(x,Mid,2*step)+Find(Mid+1,y,2*step+1);
}
}
void update(int x,int y,int z,int step)
{
if(p[step].left==x&&p[step].right==y)
p[step].value+=z;
else
{
int Mid=(p[step].left+p[step].right)/2;
if(y<=Mid)
update(x,y,z,2*step);
else
if(x>=Mid+1)
update(x,y,z,2*step+1);
else
{
update(x,Mid,z,2*step);
update(Mid+1,y,z,2*step+1);
}
p[step].sum+=(y-x+1)*z;
}
}
int main()
{
int N,Q;
int i;
char c;
int x,y,z;
p[0].sum=0;
scanf("%d%d",&N,&Q);
for(i=1;i<=N;i++)
scanf("%d",&a[i]);
build(1,N,1);
while(Q--)
{
cin>>c;
if(c=='Q')
{
scanf("%d%d",&x,&y);
printf("%I64d\n",Find(x,y,1));
}
else
{
scanf("%d%d%d",&x,&y,&z);
update(x,y,z,1);
}
}
return 0;
}