Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 78109 | Accepted: 24051 | |
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
题意:
给出了一个序列,你需要处理如下两种询问。
"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。
"Q a b" 询问[a, b]区间中所有值的和。
第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.
第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。
接下来Q行询问,格式如题目描述。
思路:
一看本题就是区间更新,与单点更新有所不同
有关update函数我们需要pushdown函数来维护整个区间的值,不是和单点更新相同,所以如下。
注意:
本题大坑:
我做的时候数组开小了,不仅sum要4倍的,而且add,num,均要四倍,一下午把我给郁闷了
维护函数:
void pushup(int v)
{
sum[v]=sum[v<<1]+sum[v<<1|1];
}
void pushdown(int l,int r,int v)
{
if(add[v]!=0)
{
add[v<<1]+= add[v]; //左子树需要加
add[v<<1|1]+=add[v]; //右子树需要加
sum[v<<1]+= (mid+1-l)*add[v];//左子树求和
sum[v<<1|1]+=(r-mid)*add[v]; //右子树求和
add[v]=0;//这儿不能少
}
}
void update(int l,int r,int v,int lpos,int rpos,int x)
{
if(l>rpos||r<lpos)
return ;
if(l>=lpos&&r<=rpos)
{
sum[v]+=(LL)(r-(l-1))*x;
add[v]+=x;
return ;
}
pushdown(l,r,v);
if(l<=mid)
update(lson,lpos,rpos,x);
if(r>mid)
update(rson,lpos,rpos,x);
pushup(v);
}
本人AC代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define MAX 100000
typedef long long int LL;
#define mid (l+r>>1)
#define lson l,mid,v<<1
#define rson mid+1,r,v<<1|1
LL sum[4*MAX+20],num[4*MAX+5],add[4*MAX+5];//注意范围
void init()
{
memset(sum,0,sizeof(sum));
memset(add,0,sizeof(add));
memset(num,0,sizeof(num));
}
void pushup(int v)
{
sum[v]=sum[v<<1]+sum[v<<1|1];
}
void pushdown(int l,int r,int v)
{
if(add[v]!=0)
{
add[v<<1]+= add[v];
add[v<<1|1]+=add[v];
sum[v<<1]+= (mid+1-l)*add[v];
sum[v<<1|1]+=(r-mid)*add[v];
add[v]=0;
}
}
void build(int l,int r,int v)
{
add[v]=0;
if(l==r)
{
sum[v]=num[l];
return ;
}
build(lson);
build(rson);
pushup(v);
}
void update(int l,int r,int v,int lpos,int rpos,int x)
{
if(l>rpos||r<lpos)//这儿剪枝不能少
return ;
if(l>=lpos&&r<=rpos)
{
sum[v]+=(LL)(r-(l-1))*x;//注意(LL)和(r-(l-1))
add[v]+=x;
return ;
}
pushdown(l,r,v);
if(l<=mid)
update(lson,lpos,rpos,x);
if(r>mid)
update(rson,lpos,rpos,x);
pushup(v);
}
LL query(int l,int r,int v,int lpos,int rpos)
{
if(l>rpos||r<lpos)//同上
return 0;
if(l>=lpos&&r<=rpos)
return sum[v];
pushdown(l,r,v);
return query(lson,lpos,rpos)+query(rson,lpos,rpos);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=1;i<=n;i++)
scanf("%lld",&num[i]);
build(1,n,1);
while(m--)
{
char opr;
getchar();//他少了会很难看的
scanf("%c",&opr);
int a,b,c;
if(opr=='Q')
{
scanf("%d%d",&a,&b);
LL ans=query(1,n,1,a,b);
printf("%lld\n",ans);
}
else
{
scanf("%d%d%d",&a,&b,&c);
update(1,n,1,a,b,c);
}
}
}
return 0;
}
队友AC代码:
#include <stdio.h>
#define N 100100
#define LL long long
#define lson l,m,v<<1
#define rson m+1,r,v<<1|1
LL add[4*N];
LL sum[4*N];
void PushUP(int v)
{
sum[v]=sum[v<<1]+sum[v<<1|1];
}
void PushDown(int v,int m)
{
if(add[v])
{
add[v<<1]+=add[v];
add[v<<1|1]+=add[v];
sum[v<<1]+=(m-(m>>1))*add[v];
sum[v<<1|1]+=(m>>1)*add[v];
add[v]=0;
}
}
void Build(int l,int r,int v)
{
add[v]=0;
if(l==r)
{
scanf("%lld",&sum[v]);
return;
}
int m=(l+r)>>1;
Build(lson);
Build(rson);
PushUP(v);
}
void Update(int L,int R,int c,int l,int r,int v)
{
if(L<=l&&R>=r)
{
add[v]+=(LL)c;
sum[v]+=(LL)c*(r-l+1);
return;
}
PushDown(v,r-l+1);
int m=(l+r)>>1;
if(L<=m)
Update(L,R,c,lson);
if(R>m)
Update(L,R,c,rson);
PushUP(v);
}
LL Query(int L,int R,int l,int r,int v)
{
if(L<=l&&R>=r)
return sum[v];
PushDown(v,r-l+1);
int m=(l+r)>>1;
LL ret=0;
if(L<=m) ret+=Query(L,R,lson);
if(R>m) ret+=Query(L,R,rson);
return ret;
}
int main()
{
int m,n;
scanf("%d%d",&n,&m);
Build(1,n,1);
for(int i=0;i<m;i++)
{
char s[2];
int a,b,c;
scanf("%s",s);
if(s[0]=='Q')
{
scanf("%d %d",&a,&b);
printf("%lld\n",Query(a,b,1,n,1));
}
else
{
scanf("%d %d %d",&a,&b,&c);
Update(a,b,c,1,n,1);
}
}
return 0;
}