【题目链接】
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=14607
【解题报告】
区间更新模板题。
操作: (L,R)区间增加V
查询:(L,R)的区间和
【参考代码】
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int INF=1e9+1e8;
const int maxn=100000+50;
int N,Q;
struct Node
{
int addv,L,R;
LL sumv;
};
Node tree[maxn*4];
void maintain( int O, int L, int R )
{
int lc=O*2, rc=O*2+1;
tree[O].sumv=0;
if( R>L )
{
tree[O].sumv=tree[lc].sumv+tree[rc].sumv;
}
tree[O].sumv+=(LL)tree[O].addv*(R-L+1);
}
void update( int O, int L, int R, int uL, int uR, int v )
{
if( L>R )return;
tree[O].L=L; tree[O].R=R;
if( uL<=L && R<=uR )
{
tree[O].addv+=v;
}
else
{
int mid=(L+R)/2;
if( uR>mid ) update( O*2+1, mid+1, R, uL, uR, v );
if( uL<=mid ) update( O*2, L, mid, uL, uR, v );
}
maintain( O, L, R );
}
LL query( int O, int L, int R, int qL, int qR, int add )
{
if( L>R )return 0;
if( qL<=L && R<=qR )
{
return tree[O].sumv+(LL)add*(R-L+1);
}
else
{
LL ans=0;
int mid=(L+R)/2;
if( qL<=mid ) ans+=query( O*2, L, mid, qL, qR ,add+tree[O].addv );
if( qR>mid ) ans+=query( O*2+1, mid+1, R, qL, qR, add+tree[O].addv );
return ans;
}
}
int main()
{
while(~scanf("%d%d",&N,&Q))
{
for( int i=1; i<=N; i++ )
{
int v;
scanf( "%d",&v );
update( 1,1,N, i,i,v );
}
// for( int i=1; i<=4*N; i++ )cout<<tree[i].L<<" "<<tree[i].R<<" "<<tree[i].sumv<<endl;
for( int i=1; i<=Q; i++ )
{
char str[2];
scanf( "%s",str );
// cout<<str<<endl;
if( str[0]=='C' )
{
// cout<<"fuck"<<endl;
int uL, uR, uV;
scanf( "%d%d%d",&uL,&uR,&uV );
//cout<<uL<<" "<<uR<<" "<<uV<<endl;
update( 1,1,N,uL,uR, uV );
}
else
{
int qL,qR;
scanf("%d%d",&qL, &qR);
// cout<<qL<<" "<<qR<<endl;
printf( "%I64d\n", query( 1,1,N, qL,qR ,0 ) );
}
}
}
return 0;
}