线段树

来源:互联网 发布:国家发改委 大数据 编辑:程序博客网 时间:2024/06/07 16:17
#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <string>#include <iostream>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <deque>#include <map>#include <set>using std::cin;using std::cout;using std::endl;typedef long long ll;const int maxn=524300;int n,m;ll tree[maxn];ll lazy[maxn];void build(int node = 1, int l = 1, int r = n){    if(l==r)    {        scanf("%lld",&tree[node]);        return;    }    int mid=(l+r)/2;    int lc=node<<1;    int rc=(node<<1)+1;    build(lc, l, mid);    build(rc, mid+1, r);    tree[node] = tree[lc] + tree[rc];}void pushdown(int node, int l, int r){    if(lazy[node])    {        int lc=node<<1;        int rc=(node<<1)+1;        lazy[lc]+=lazy[node];        lazy[rc]+=lazy[node];        int mid=(l+r)/2;        tree[lc]+=lazy[node] * (mid-l+1);        tree[rc]+=lazy[node] * (r-mid);        lazy[node]=0;    }}int g_L,g_R;ll g_x;void update(int node = 1, int l = 1, int r = n){    if(g_L<=l && r<=g_R)    {        tree[node]+=g_x * (r-l+1);        lazy[node]+=g_x;        return;    }    int mid=(l+r)/2;    int lc=node<<1;    int rc=(node<<1)+1;    pushdown(node, l, r);    if(g_L<=mid)    {        update(lc,l,mid);    }    if(g_R>mid)    {        update(rc,mid+1,r);    }    tree[node]=tree[lc]+tree[rc];}ll query(int node = 1, int l = 1, int r = n){    if(g_L<=l && r<=g_R)    {        return tree[node];    }    int mid=(l+r)/2;    int lc=node<<1;    int rc=(node<<1)+1;    pushdown(node, l, r);    ll sum=0;    if(g_L<=mid)    {        sum+=query(lc,l,mid);    }    if(g_R>mid)    {        sum+=query(rc,mid+1,r);    }    return sum;}int main(){    scanf("%d",&n);    build();    scanf("%d",&m);    while(m--)    {        int ins;        scanf("%d",&ins);        if(ins==1)        {            scanf("%d%d%lld",&g_L,&g_R,&g_x);            update();        }        else if(ins==2)        {            scanf("%d%d",&g_L,&g_R);            printf("%lld\n",query());        }    }    return 0;}