题意:给出一串数列,有两种操作。Q ( x, y ) 表示输出数列的第 x -- y 个元素的和。 C(x,y,z) 表示将 x - y 的所有元素均加上 z。
题解:线段树很容易。但是听说这题可以用树状数组解,在网上搜了下,暂且把地址记下来。树状数组http://kenby.iteye.com/blog/962159
#include <iostream>
using namespace std;
#define L(u) ( u << 1 )
#define R(u) ( u << 1 | 1 )
#define lint __int64
#define N 100005
lint sum[N], n, q;
struct item
{
int l, r;
lint v, add;
} node[N*3];
void build ( int u, int l, int r )
{
node[u].l = l;
node[u].r = r;
node[u].add = 0;
node[u].v = sum[r] - sum[l-1];
if ( l == r ) return;
int mid = ( l + r ) >> 1;
build ( L(u), l, mid );
build ( R(u), mid+1, r );
}
void update ( int u, int l, int r, lint val )
{
if ( l == node[u].l && node[u].r == r )
{
node[u].add += val;
node[u].v += val * ( r - l + 1 );
return;
}
if ( node[u].add != 0 )
{
node[L(u)].add += node[u].add;
node[L(u)].v += node[u].add * ( node[L(u)].r - node[L(u)].l + 1 );
node[R(u)].add += node[u].add;
node[R(u)].v += node[u].add * ( node[R(u)].r - node[R(u)].l + 1 );
node[u].add = 0;
}
int mid = ( node[u].l + node[u].r ) >> 1;
if ( r <= mid )
update ( L(u), l, r, val );
else if ( l > mid )
update ( R(u), l, r, val );
else
{
update ( L(u), l, mid, val );
update ( R(u), mid+1, r, val );
}
node[u].v = node[L(u)].v + node[R(u)].v;
}
lint query ( int u, int l, int r )
{
if ( l == node[u].l && node[u].r == r )
return node[u].v;
if ( node[u].add != 0 )
{
node[L(u)].add += node[u].add;
node[L(u)].v += node[u].add * ( node[L(u)].r - node[L(u)].l + 1 );
node[R(u)].add += node[u].add;
node[R(u)].v += node[u].add * ( node[R(u)].r - node[R(u)].l + 1 );
node[u].add = 0;
}
int mid = ( node[u].l + node[u].r ) >> 1;
if ( r <= mid)
return query ( L(u), l, r );
else if ( l > mid )
return query ( R(u), l, r );
else
return query ( L(u), l, mid ) + query ( R(u), mid+1, r );
}
int main()
{
char oper[3];
int x, y; lint num;
while ( scanf("%d%d",&n,&q) != EOF )
{
sum[0] = 0;
for ( int i = 1; i <= n; i++ )
{
scanf("%I64d",&num);
sum[i] = sum[i-1] + num;
}
build ( 1, 1, n );
while ( q-- )
{
scanf("%s",oper);
if ( oper[0] == 'C' )
{
scanf("%d%d%I64d",&x,&y,&num);
update ( 1, x, y, num );
}
else
{
scanf("%d%d",&x,&y);
printf("%I64d\n",query(1,x,y));
}
}
}
return 0;
}