成段加值更新 区间求和 poj3468 A Simple Problem with Integers

来源:互联网 发布:即时通讯软件排行 编辑:程序博客网 时间:2024/06/05 10:38

题目链接  poj3468 A Simple Problem with Integers

题目大意:给你n个附有起始值的数,然后m次询问。C  a b val :表示区间[a,b]的数都加上一个val值,Q a b :询问区间[a,b]的综合。

解题思路:O(-1)

#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define lz 2*u,l,mid#define rz 2*u+1,mid+1,rconst int maxn=100005;__int64 a[maxn];     ///还要注意范围__int64 tree[4*maxn];__int64 flag[4*maxn];void push_up(int u){    tree[u]=tree[2*u]+tree[2*u+1];}void push_down(int u, int l, int r){    if(flag[u])    {        int mid=(l+r)>>1;        flag[2*u]+=flag[u];  ///!!!        flag[2*u+1]+=flag[u];  ///!!!        tree[2*u]+=flag[u]*(mid-l+1);        tree[2*u+1]+=flag[u]*(r-mid);        flag[u]=0;    }}void build(int u, int l, int r){    flag[u]=0;    if(l==r)    {        tree[u]=a[l];        return ;    }    int mid=(l+r)>>1;    build(lz);    build(rz);    push_up(u);}void Update(int u, int l, int r, int tl, int tr, __int64 val){    if(tl<=l&&r<=tr)    {        tree[u]+=val*(r-l+1);        flag[u]+=val;  ///!!!加上一个值 并非重新赋新值        return ;    }    push_down(u,l,r);    int mid=(l+r)>>1;    if(tr<=mid)        Update(lz,tl,tr,val);    else if(tl>mid)         Update(rz,tl,tr,val);    else    {        Update(lz,tl,mid,val);        Update(rz,mid+1,tr,val);    }    push_up(u);}__int64 Query(int u, int l, int r, int tl, int tr){    if(tl<=l&&r<=tr)    {        return tree[u];    }    push_down(u,l,r);    int mid=(l+r)>>1;    if(tr<=mid)        return Query(lz,tl,tr);    else if(tl>mid)         return Query(rz,tl,tr);    else    {        __int64 t1=Query(lz,tl,mid);        __int64 t2=Query(rz,mid+1,tr);        return t1+t2;    }    push_up(u);}int main(){    int n, m, l, r;    while(cin >> n >> m)    {        for(int i=1; i<=n; i++)            scanf("%I64d",a+i);        build(1,1,n);        while(m--)        {            char ch[5];            __int64 val;            scanf("%s",ch);            if(ch[0]=='C')            {                scanf("%d%d%I64d",&l,&r,&val);                Update(1,1,n,l,r,val);            }            else            {                scanf("%d%d",&l,&r);                printf("%I64d\n",Query(1,1,n,l,r));            }        }    }    return 0;}


0 0
原创粉丝点击