题目分析
题目的意思我就不多说了,这里我主要学习了一下线段树的模板,并且精简了一下代码,作为一个模板存下来吧。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long LL;
const int maxn = 100005;
#define mid (L+R)/2
#define lson o << 1, L, mid
#define rson o << 1 | 1, mid+1, R
LL sum[4*maxn],add[4*maxn];
void pushup(int o){
sum[o] = sum[o<<1] + sum[o<<1|1];
}
void pushdown(int o,int L,int R){
if(add[o])
{
sum[o<<1] += add[o]*(mid-L+1);
sum[o<<1|1] += add[o]*(R-mid);
add[o<<1] += add[o];
add[o<<1|1] += add[o];
add[o] = 0;
}
}
void build(int o,int L,int R)
{
add[o] = 0;
if(L == R)
{
scanf("%I64d", &sum[o]);
return ;
}
build(lson);
build(rson);
pushup(o);
}
void update(int o,int L,int R,int x,int y,int v)
{
if(x <= L && R <= y)
{
sum[o] += v*(R-L+1);
add[o] += v;
return ;
}
pushdown(o, L, R);
if(x <= mid) update(lson,x,y,v);
if(y > mid) update(rson,x,y,v);
pushup(o);
}
LL query(int o,int L,int R,int x,int y)
{
if(x <= L && R <= y)
return sum[o];
pushdown(o, L, R);
LL ret = 0;
if(x <= mid) ret += query(lson,x,y);
if(y > mid) ret += query(rson,x,y);
return ret;
}
int main()
{
int N,M;
while(scanf("%d%d", &N, &M) != EOF)
{
build(1,1,N);
char op;
int x,y,v;
while(M--)
{
cin >> op;
if(op == 'Q')
{
scanf("%d%d", &x, &y);
printf("%I64d\n", query(1,1,N,x,y));
}
else
{
scanf("%d%d%d", &x, &y, &v);
update(1,1,N,x,y,v);
}
}
}
return 0;
}