给出了一个序列,你需要处理如下两种询问。
"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。
"Q a b" 询问[a, b]区间中所有值的和。
Input
第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.
第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。
接下来Q行询问,格式如题目描述。
Output
对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。
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
模板题
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define eps 0.00000001
using namespace std;
int q[400000];
struct point
{
int l,r;
long long nsum;
long long add;
}node[400000];
void Build(int P,int L,int R)
{
node[P].l=L;
node[P].r=R;
node[P].add=0;
if(L==R)
{
node[P].nsum=q[L];
return ;
}
int mid=L+((R-L)>>1);
Build(P<<1,L,mid);
Build(P<<1|1,mid+1,R);
node[P].nsum=node[P<<1].nsum+node[P<<1|1].nsum;
}
void Add(int P,int L,int R,long long c)
{
if(node[P].l==L&&node[P].r==R)
{
node[P].add+=c;
return ;
}
node[P].nsum+=c*(R-L+1);
int mid=(node[P].l+node[P].r)>>1;
if(R<=mid) Add(P<<1,L,R,c);
else if(L>mid) Add(P<<1|1,L,R,c);
else
{
Add(P<<1,L,mid,c);
Add(P<<1|1,mid+1,R,c);
}
}
long long Query(int P,int L,int R)
{
if(node[P].l==L&&node[P].r==R)
{
return node[P].nsum+(R-L+1)*node[P].add;
}
node[P].nsum+=(node[P].r-node[P].l+1)*node[P].add;
int mid=(node[P].l+node[P].r)>>1;
Add(P<<1,node[P].l,mid,node[P].add);
Add(P<<1|1,mid+1,node[P].r,node[P].add);
node[P].add=0;
if(R<=mid) return Query(P<<1,L,R);
else if(L>mid) return Query(P<<1|1,L,R);
else return Query(P<<1,L,mid)+Query(P<<1|1,mid+1,R);
}
int main()
{
int n,m,i;
int a,b,c;
char s[10];
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=n;i++)
{
scanf("%d",&q[i]);
}
Build(1,1,n);
for(i=0;i<m;i++)
{
scanf("%s",s);
if(s[0]=='C')
{
scanf("%d%d%d",&a,&b,&c);
Add(1,a,b,c);
}
else
{
scanf("%d%d",&a,&b);
cout<<Query(1,a,b)<<endl;
}
}
}
return 0;
}