Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 68379 | Accepted: 21081 | |
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
Source
#include <stdio.h>
#include <string.h>
#define ll long long
ll d[100010 << 2];
ll lz[100010 << 2];
ll sum;
void up(int step)
{
d[step] = d[step << 1] + d[step << 1 | 1];
}
void down(int s,int t,int step)
{
ll m = t - s + 1;
d[step << 1] += (m - (m >> 1)) * lz[step];
d[step << 1 | 1] += (m >> 1) * lz[step];
lz[step << 1] += lz[step];
lz[step << 1 | 1] += lz[step];
lz[step] = 0;
}
void build(ll s,ll t,ll step)
{
lz[step] = 0;
if(s >= t)
{
scanf("%lld",&d[step]);
return ;
}
ll mid = (s + t) >> 1;
build(s,mid,step << 1);
build(mid + 1,t,step << 1 | 1);
up(step);
}
void que(ll s,ll t,ll qs,ll qt,ll step)
{
if(s > qt || t < qs)
return ;
if(s >= t)
{
sum += d[step];
return ;
}
if(qs <= s && t <= qt)
{
sum += d[step];
return ;
}
if(lz[step])
down(s,t,step);
ll mid = (s + t) >> 1;
if(qs <= mid)
que(s,mid,qs,qt,step << 1);
if(qt > mid)
que(mid + 1,t,qs,qt,step << 1 | 1);
}
void upd(ll s,ll t,ll us,ll ut,ll unum,ll step)
{
if(s > ut || t < us)
return ;
if(s >= t)
{
d[step] += unum;
return ;
}
if(us <= s && t <= ut)
{
lz[step] += unum;
d[step] += (t - s + 1) * unum;
return ;
}
if(lz[step])
down(s,t,step);
ll mid = (s + t) >> 1;
if(us <= mid)
upd(s,mid,us,ut,unum,step << 1);
if(ut > mid)
upd(mid + 1,t,us,ut,unum, step << 1 | 1);
up(step);
}
int main()
{
ll n,k,qs,qt,us,ut,unum;
char str[5];
while(~scanf("%lld%lld",&n,&k))
{
build(1,n,1);
while(k--)
{
scanf("%s",str);
if(str[0] == 'Q')
{
scanf("%lld%lld",&qs,&qt);
sum = 0;
que(1,n,qs,qt,1);
printf("%lld\n",sum);
}
else if(str[0] == 'C')
{
scanf("%lld%lld%lld",&us,&ut,&unum);
upd(1,n,us,ut,unum,1);
}
}
}
return 0;
}