【线段树模板】

来源:互联网 发布:暖手袋 知乎 编辑:程序博客网 时间:2024/06/06 07:10

求和模板

#include <cstdio>#include <iostream>#include <algorithm>using namespace std;const int maxn=100000+100;struct SegmentTree{    int l,r,lz,sum;}tree[maxn<<2];int n,Q,cnt;char s[3];int a[maxn];void push_down(int i){    tree[i].sum+=(tree[i].r-tree[i].l+1)*tree[i].lz;    tree[i<<1].lz+=tree[i].lz;    tree[(i<<1)|1].lz+=tree[i].lz;    tree[i].lz=0;}void build(int i,int l,int r){    tree[i].l=l,tree[i].r=r;    if(l==r)    {        tree[i].lz=0;        tree[i].sum=a[++cnt];        return;    }    int mid=(l+r)>>1;    build(i<<1,l,mid);    build((i<<1)|1,mid+1,r);    tree[i].sum=tree[i<<1].sum+tree[(i<<1)|1].sum;}void update(int i,int l,int r,int v){    if(tree[i].l==l&&tree[i].r==r)    {        tree[i].lz+=v;        return;    }    tree[i].sum+=(r-l+1)*v;    if(tree[i].lz)    {        push_down(i);    }    int mid =(tree[i].l+tree[i].r)>>1;    if(r<=mid) update(i<<1,l,r,v);    else if(l>mid) update((i<<1)|1,l,r,v);    else    {        update(i<<1,l,mid,v);        update((i<<1)|1,mid+1,r,v);    }}int q(int i,int l,int r){    if(tree[i].l==l&&tree[i].r==r)        return tree[i].sum+(r-l+1)*tree[i].lz;    if(tree[i].lz) push_down(i);    int mid=(tree[i].r+tree[i].l)>>1;    if(r<=mid) return q(i<<1,l,r);    else if(l>mid) return q((i<<1)|1,l,r);    else return q(i<<1,l,mid)+q((i<<1)|1,mid+1,r);}int main(){    int x,y,z;    scanf("%d%d",&n,&Q);    for(int i=1;i<=n;i++)        scanf("%d",&a[i]);    cnt=0;    build(1,1,n);    while(Q--)    {        scanf("%s",s);        if(s[0]=='Q')        {            scanf("%d%d",&x,&y);            printf("%d\n",q(1,x,y));        }        else if(s[0]=='C')        {            scanf("%d%d%d",&x,&y,&z);            update(1,x,y,z);        }    }    return 0;}
原创粉丝点击