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.
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.
You need to answer all Q commands in order. One answer in a line.
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
4
55
9
15
The sums may exceed the range of 32-bit integers.
额,简单的线段树区间维护,最后那个hint一直没看到,哭了……
#include
#include
#include
using namespace std;
typedef long long ll;
ll tree[400005],Add[400005];
void pushup(int i)
{
tree[i]=tree[2*i]+tree[2*i+1];
}
void pushdown(int i,int l)
{
if(Add[i])
{
Add[2*i]+=Add[i];
Add[2*i+1]+=Add[i];
tree[2*i]+=Add[i]*(l-l/2);
tree[2*i+1]+=Add[i]*(l/2);
Add[i]=0;
}
}
void build(int i,int l,int r)
{
if (l==r) {
scanf("%lld",&tree[i]);
return ;
}
int mid=l+(r-l)/2;
build(2*i,l,mid);
build(2*i+1,mid+1,r);
pushup(i);
}
void add(int i,int l,int r,int x,int y,int k)
{
if(x<=l && r<=y)
{
Add[i]+=k;
tree[i]+=(r-l+1)*k;
return ;
}
pushdown(i,r-l+1);
int mid=l+(r-l)/2;
if(x<=mid) add(2*i,l,mid,x,y,k);
if(y>mid) add(2*i+1,mid+1,r,x,y,k);
pushup(i);
}
ll query(int i,int l,int r,int m,int n)
{
ll sum=0;
if(m<=l && r<=n){
return tree[i];
}
pushdown(i,r-l+1);//查询时也要将附加值向下传递,否则WA
int mid=l+(r-l)/2;
if (m<=mid) sum+=query(2*i,l,mid,m,n);
if (n>mid) sum+=query(2*i+1,mid+1,r,m,n);
return sum;
}
int main()
{
ll m,n,x,y,k;
char t;
cin>>n>>m;
build(1,1,n);
while(m--)
{
cin>>t;
if(t=='Q')
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(1,1,n,x,y));
}
else
{
scanf("%lld%lld%lld",&x,&y,&k);
add(1,1,n,x,y,k);
}
}
}