您的位置:首页 > 其它

POJ:3468 A Simple Problem with Integers(线段树模版题)

2014-03-16 19:30 411 查看
题意:给一串数字,有区间加减和求和操作。

思路:线段树区间加减,区间求和。注意要用longlong。模版题。

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int maxn=100005<<2;
struct LineTree
{
    LL sum[maxn],tar[maxn];
    void build(int o,int L,int R)
    {
        tar[o]=0;
        if(L==R)
            scanf("%lld",&sum[o]);
        else
        {
            int M=L+(R-L)/2;
            build(o<<1,L,M);
            build(o<<1|1,M+1,R);
            push_up(o);
        }
    }
    void push_up(int o)
    {
        sum[o]=sum[o<<1]+sum[o<<1|1];
    }
    void push_down(int o,int m)
    {
        if(tar[o])
        {
            tar[o<<1]+=tar[o];
            tar[o<<1|1]+=tar[o];
            sum[o<<1]+=tar[o]*(m-m/2);
            sum[o<<1|1]+=tar[o]*(m/2);
            tar[o]=0;
        }
    }
    void add(int o,LL c,int ql,int qr,int L,int R)
    {
        if(ql<=L&&R<=qr)
        {
            sum[o]+=c*(R-L+1);
            tar[o]+=c;
        }
        else
        {
            int M=L+(R-L)/2;
            push_down(o,R-L+1);
            if(ql<=M) add(o<<1,c,ql,qr,L,M);
            if(M<qr) add(o<<1|1,c,ql,qr,M+1,R);
            push_up(o);
        }
    }
    LL query(int o,int ql,int qr,int L,int R)
    {
        if(ql<=L&&R<=qr)
            return sum[o];
        else
        {
            LL s=0;
            int M=L+(R-L)/2;
            push_down(o,R-L+1);
            if(ql<=M) s+=query(o<<1,ql,qr,L,M);
            if(M<qr) s+=query(o<<1|1,ql,qr,M+1,R);
            return s;
        }
    }
};
LineTree tree;
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        tree.build(1,1,n);
        while(m--)
        {
            char s[5];
            scanf("%s",s);
            if(s[0]=='Q')
            {
                int a,b;
                scanf("%d%d",&a,&b);
                printf("%lld\n",tree.query(1,a,b,1,n));
            }
            else
            {
                int a,b;
                LL c;
                scanf("%d%d%lld",&a,&b,&c);
                tree.add(1,c,a,b,1,n);
            }
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: