poj 3468 A Simple Problem with Integers 线段树

来源:互联网 发布:你什么都不懂琼恩 知乎 编辑:程序博客网 时间:2024/05/10 18:48

线段树的区间加减数,区间查询

#include <cstdio>#include <algorithm>using namespace std;#define LL __int64const int maxn = 100100;LL sum[4*maxn];LL add[4*maxn];void build(int l,int r,int o){    add[o]=0;    if(l==r)    {        scanf("%I64d",&sum[o]);        return ;    }    int m=(l+r)/2;    build(l,m,2*o);    build(m+1,r,2*o+1);    sum[o]=sum[2*o]+sum[2*o+1];}void update(int ql,int qr,int z,int l,int r,int o){    if(ql<=l&&r<=qr)    {        add[o]+=z;        sum[o]+=(LL)z*(r-l+1);        return ;    }    if(add[o])    {        add[2*o]+=add[o];        add[2*o+1]+=add[o];        sum[o*2] += add[o] * (r-l+1 - (r-l+1)/2);sum[o*2+1] += add[o] * ((r-l+1)/2);add[o]=0;    }    int m=(l+r)/2;    if(ql<=m) update(ql,qr,z,l,m,2*o);    if(qr>m) update(ql,qr,z,m+1,r,2*o+1);    sum[o]=sum[2*o]+sum[2*o+1];}LL query(int ql,int qr,int l,int r,int o){    if(ql<=l&&r<=qr)        return sum[o];    if(add[o])    {        add[2*o]+=add[o];        add[2*o+1]+=add[o];        sum[o*2] += add[o] * (r-l+1 - (r-l+1)/2);sum[o*2+1] += add[o] * ((r-l+1)/2);add[o]=0;    }    LL ans=0;    int m=(l+r)/2;    if(ql<=m) ans+=query(ql,qr,l,m,2*o);    if(qr>m) ans+=query(ql,qr,m+1,r,2*o+1);    return ans;}int main(){    int n,q;    while(scanf("%d%d",&n,&q)!=EOF)    {        build(1,n,1);        char c;        int i,j;int x,y,z;getchar();        for(i=1;i<=q;i++)        {            scanf("%c",&c);            if(c=='Q')            {                scanf("%d%d",&x,&y);                printf("%I64d\n",query(x,y,1,n,1));            }            else            {                scanf("%d%d%d",&x,&y,&z);                update(x,y,z,1,n,1);            }getchar();        }    }    return 0;}


 

0 0
原创粉丝点击