亮皇轻轻松松在大学四年间拿到了北理工rk0,也有很多家公司给他了offer,但是他看了看觉得薪水都太低了,并不想参加,于是决定回家种地。
他在家里开始种西瓜,家里一共有nn块瓜田,每年可以产出aiai个西瓜。每年亮皇回家的时候都会看看他种的这块地,他会做以下下两种操作之一:
- 询问一段土地从第一年开始,到当年结束一共生产了多少个西瓜。
- 在一段土地上种上黄豆,这样可以让这块西瓜地从下一年开始产量+1。
亮皇一共会回家mm年,请你帮他回答所有的查询。
Input
输入数据包括多组数据(不超过8组),请处理到文件结束。
对于每一组数据,第一行包括一个整数n(1≤n≤105)n(1≤n≤105),表示西瓜地的数量。
第二行包括nn个整数,表示初始年产量ai(ai≤105)ai(ai≤105)。
第三行包括mm个整数,表示亮皇要回家m(1≤m≤105)m(1≤m≤105)年。
接下来mm行,每行一定是以下两种形式之一:
- "Q s t":查询第[s,t][s,t]块土地上从开始种地到当年结束的总产量。
- "I s t":当年在第[s,t][s,t]块土地上种上黄豆。
数据保证至少有一次查询操作。
Output
对于每一组数据,在一行内回答所有的查询,用空格隔开。
Example
Input
4 1 1 1 1 3 Q 1 3 Q 1 4 Q 2 4 4 1 2 3 4 3 Q 1 4 I 1 3 Q 2 4
Output
3 8 9 10 29
建两颗线段树,一颗记录当前的年产量,另一颗记录多算的产量(每个点多算的产量为当前的年份),总产量 = 年产量×年份-多算的
#include<stdio.h>
#include<string.h>
#define lson num<<1
#define rson num<<1|1
#define mid ((l+r)>>1)
long long a[1200000],b[1200000],la[1200000],lb[1200000],flag,z[120000];
long long ans1,ans2;
void down(long long l,long long r,long long num)
{
la[lson] += la[num];
la[rson] += la[num];
a[lson] += la[num]*(mid-l+1);
a[rson] += la[num]*(r-mid);
la[num] = 0;
}
void down1(long long l,long long r,long long num)
{
lb[lson] += lb[num];
lb[rson] += lb[num];
b[lson] += lb[num]*(mid-l+1);
b[rson] += lb[num]*(r-mid);
lb[num] = 0;
}
void build(long long l, long long r, long long num)
{
if(l == r)
{
scanf("%lld",&a[num]);
return;
}
if(la[num] > 0)
down(l,r,num);
build(l,mid,lson);
build(mid+1,r,rson);
a[num] = a[lson] + a[rson];
}
void sum(long long x, long long y,long long l, long long r,long long num)
{
if(x<= l&&y >= r)
{
ans1 += a[num];
return ;
}
if(la[num] > 0)
down(l,r,num);
if(x <= mid)
sum(x,y,l,mid,lson);
if(y > mid)
sum(x,y,mid+1,r,rson);
}
void sum1(long long x, long long y,long long l, long long r,long long num)
{
if(x<= l&&y >= r)
{
ans2 += b[num];
return ;
}
if(lb[num] > 0)
down1(l,r,num);
if(x <= mid)
sum1(x,y,l,mid,lson);
if(y > mid)
sum1(x,y,mid+1,r,rson);
}
void plus(long long x, long long y,long long l, long long r, long long num)
{
if(l >= x&&r <= y)
{
la[num] += flag;
a[num] += flag*(r-l+1);
return;
}
if(la[num] > 0)
down(l,r,num);
if(x <= mid)
plus(x,y,l,mid,lson);
if(y > mid)
plus(x,y,mid+1,r,rson);
a[num] = a[lson] +a[rson];
}
void plus1(long long x, long long y,long long l, long long r, long long num)
{
if(l >= x&&r <= y)
{
lb[num] += flag;
b[num] += flag*(r-l+1);
return;
}
if(lb[num] > 0)
down1(l,r,num);
if(x <= mid)
plus1(x,y,l,mid,lson);
if(y > mid)
plus1(x,y,mid+1,r,rson);
b[num] = b[lson] + b[rson];
}
int main()
{
long long i,j,m,n,aa,bb,tail;
char s[5];
while(scanf("%lld",&n) !=EOF)
{
tail = -1;
memset(b,0,sizeof(b));
memset(la,0,sizeof(la));
memset(lb,0,sizeof(lb));
build(1,n,1);
scanf("%lld",&m);
for(i = 1; i <= m; i ++)
{
scanf("%s %lld %lld",s,&aa,&bb);
if(s[0] == 'Q')
{
ans1 = ans2 = 0;
sum(aa,bb,1,n,1) ;
sum1(aa,bb,1,n,1);
// prlong long f("%d\n",ans1*i-ans2);
z[++tail] = ans1*i-ans2;
}
else
{
flag = 1;
plus(aa,bb,1,n,1);
flag = i;
plus1(aa,bb,1,n,1);
}
}
for(i = 0; i <= tail; i ++)
{
if(i == tail)
printf("%lld\n",z[i]);
else
printf("%lld ",z[i]);
}
}
return 0;
}