思路:
线段树模板题
c o d e code code
#include<iostream>
#include<cstdio>
using namespace std;
long long n, m;
struct node
{
long long l, r, sum, flag;
}tree[4001000];
void build(long long k, long long l, long long r)
{
tree[k].l=l, tree[k].r=r;
if(l==r)
{
scanf("%lld", &tree[k].sum);
return;
}
long long mid=l+r>>1;
build(k*2, l, mid);
build(k*2+1, mid+1, r);
tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
}
void down(long long k)
{
tree[k*2].flag+=tree[k].flag;
tree[k*2+1].flag+=tree[k].flag;
tree[k*2].sum+=(tree[k*2].r-tree[k*2].l+1)*tree[k].flag;
tree[k*2+1].sum+=(tree[k*2+1].r-tree[k*2+1].l+1)*tree[k].flag;
tree[k].flag=0;
}
void change(long long k, long long l, long long r, long long x, long long y, long long v)
{
if(x<=l&&r<=y)
{
tree[k].sum+=(r-l+1)*v;
tree[k].flag+=v;
return;
}
if(tree[k].flag)
down(k);
long long mid=l+r>>1;
if(x<=mid)
change(k*2, l, mid, x, y, v);
if(y>mid)
change(k*2+1, mid+1, r, x, y, v);
tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
}
long long query(long long k, long long l, long long r, long long x, long long y)
{
if(x<=l&&r<=y)
return tree[k].sum;
if(tree[k].flag)
down(k);
long long mid=l+r>>1, res=0;
if(x<=mid)
res+=query(k*2, l, mid, x, y);
if(y>mid)
res+=query(k*2+1, mid+1, r, x, y);
return res;
}
int main()
{
scanf("%lld%lld", &n, &m);
build(1, 1, n);
while(m--)
{
long long x, y, z, k;
scanf("%lld%lld%lld", &z, &x, &y);
if(z==1)
{
scanf("%lld", &k);
change(1, 1, n, x, y, k);
}
else
printf("%lld\n", query(1, 1, n, x, y));
}
return 0;
}