Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 93547 | Accepted: 29145 | |
Case Time Limit: 2000MS |
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
#include<stdio.h>
#include<string.h>
#include<math.h>
//线段树
//用途:快速区间更新,区间查询最值或和
//初始化(多组数据):Initialize()
//注意事项:所有函数调用时前3个参数均填写为:1, 1, n,其他参数下方具体描述。默认为单点修改,区间求和,其他需求请自行更改
int n, q;
const int MAX = 200000+1;
//区间更新、区间查询(只能查询区间和)
//il、ir分别为目标区间的左、右端点下标,value为要更新的值
long long st[MAX*6];
long long lazy[MAX*6];
void Initialize()
{
memset(st, 0, sizeof(st));
memset(lazy, 0, sizeof(lazy));
}
void Update(int node, int l, int r, int il, int ir, long long value)
{
int mid = (l + r) >> 1;
if(lazy[node])
{
lazy[node<<1] += lazy[node];
lazy[node<<1|1] += lazy[node];
st[node<<1] += (mid-l+1) * lazy[node];
st[node<<1|1] += (r-mid) * lazy[node];
lazy[node] = 0;
}
if(l==il && r==ir)
{
lazy[node] += value;
st[node] += (r-l+1) * value;
return;
}
if(ir <= mid)
Update(node<<1, l, mid, il, ir, value);
else if(il > mid)
Update(node<<1|1, mid+1, r, il, ir, value);
else
{
Update(node<<1, l, mid, il, mid, value);
Update(node<<1|1, mid+1, r, mid+1, ir, value);
}
st[node] = st[node<<1] + st[node<<1|1];
}
long long Query(int node, int l, int r, int il, int ir)
{
int mid = (l + r) >> 1;
if(lazy[node])
{
lazy[node<<1] += lazy[node];
lazy[node<<1|1] += lazy[node];
st[node<<1] += (mid-l+1) * lazy[node];
st[node<<1|1] += (r-mid) * lazy[node];
lazy[node] = 0;
}
if(l==il && r==ir)
return st[node];
if(ir <= mid)
return Query(node<<1, l, mid, il, ir);
else if(il > mid)
return Query(node<<1|1, mid+1, r, il, ir);
else
return Query(node<<1, l, mid, il, mid) +
Query(node<<1|1, mid+1, r, mid+1, ir);
}
int main()
{
while(~scanf("%d%d", &n,&q))
{
Initialize();
int a, b;
long long x;
for(int i = 1; i<=n; ++i)
{
scanf("%lld", &x);
Update(1, 1, n, i, i, x);
}
char s[2];
while(q--)
{
scanf("%s", s);
if(s[0]=='Q')
{
scanf("%d%d",&a, &b);
if(a>b)
{
a+=b;
b=a-b;
a-=b;
}
printf("%lld\n", Query(1,1,n,a,b));
}
else if(s[0]=='C')
{
scanf("%d%d%lld", &a, &b,&x);
if(a>b)
{
a+=b;
b=a-b;
a-=b;
}
Update(1, 1, n, a, b, x);
}
}
}
return 0;
}