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 abc" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q ab" 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
# include <cstdio>
# include <iostream>
# define MN 400000
using namespace std;
long long a[100005];
struct node{
int left,right,mid;
long long add,x;
}tree[MN];
void build(int le,int ri,int num)//构建一个线段树
{
tree[num].left= le;
tree[num].right = ri;
tree[num].add = 0;
tree[num].mid = (le + ri) /2;
if(le!=ri)
{
build(le,tree[num].mid,num*2);
build(tree[num].mid+1,ri,num*2+1);
tree[num].x=tree[num*2].x+tree[num*2+1].x;
}
else
{
tree[num].x=a[le];
return ;
}
}
void change(int le,int ri,int num,int cha)//在一段连续的序列里改变数值
{
if(tree[num].left==le&&tree[num].right==ri)
{
tree[num].add += cha;
tree[num].x += cha*(ri-le+1);
return ;
}
if(tree[num].add)
{
tree[num*2].add+=tree[num].add;//将加的数传下去
tree[num*2+1].add += tree[num].add;
tree[2*num].x += tree[num].add*(tree[2*num].right-tree[2*num].left+1);
tree[2*num+1].x += tree[num].add*(tree[2*num+1].right-tree[2*num+1].left+1);
tree[num].add=0;
}
if(ri<=tree[num].mid)
change(le,ri,num*2,cha);
else if(le>tree[num].mid)
change(le,ri,num*2+1,cha);
else
{
change(le,tree[num].mid,num*2,cha);
change(tree[num].mid+1,ri,num*2+1,cha);
}
tree[num].x=(tree[num*2].x + tree[num*2+1].x);
// cout<<"tree["<<num<<"].x"<<tree[num].x<<endl;
}
long long getsum(int le,int ri,int num)// 求和
{
if (le==tree[num].left && ri==tree[num].right)
return tree[num].x ; // 找到,返回
if(tree[num].add)
{
tree[2*num].add += tree[num].add;
tree[2*num+1].add += tree[num].add;
tree[2*num].x += tree[num].add*(tree[2*num].right-tree[2*num].left+1);
tree[2*num+1].x += tree[num].add*(tree[2*num+1].right-tree[2*num+1].left+1);
tree[num].add = 0;
}
if(le>tree[num].mid)
return getsum(le,ri,2*num+1);
else if(ri<=tree[num].mid)
return getsum(le,ri,2*num);
else
{
return getsum(le,tree[num].mid,2*num)+getsum(tree[num].mid+1,ri,2*num+1);
}
}
int main()
{
int N,Q,i,j;
while(~scanf("%d %d",&N,&Q))
{
for (i=1;i<=N;i++)
scanf("%lld",&a[i]);
getchar();
build(1,N,1);
char T;
int m,t,l,r,c;
for (j=Q;j>0;j--)
{
scanf("%c",&T);
if(T=='Q')
{
scanf("%d%d",&l,&r);
getchar();
cout << getsum(l,r,1) << endl;
}
else {
scanf("%d%d%d",&l,&r,&m);
getchar();
change(l,r,1,m);
}
}
}
return 0;
}
/*
10 22
1 2 3 4 5 6 7 8 9 10
Q 4 4
C 1 10 3
C 6 10 3
C 6 9 3
C 8 9 -100
C 7 9 3
C 7 10 3
C 1 10 3
Q 6 10
Q 6 9
Q 8 9
Q 7 9
Q 7 10
Q 1 10
Q 2 4
C 3 6 3
Q 9 9
Q 1 1
Q 5 5
Q 6 6
Q 7 7
Q 6 8
4
-82
-104
-147
-122
-100
-37
27
-73
7
14
21
25
-28
*/