POJ3468 A Simple Problem with Integers(区间求和线段树模板题)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
using namespace std;
const int maxn = 100004;
struct node
{
    long long val;
    long long addmark;
} ST[4*maxn+5];
long long A[maxn];
//修改求和还是维护区间最小值
long long operation(long long a,long long b)
{
    return a+b;
    //return max_min(a,b);
}
//修改求和还是维护区间最小值
void change(int pos,long long addmark,int l)
{
    ST[pos].val +=addmark*l;
}
void build(int root,int ibegin,int iend)
{
    ST[root].addmark = 0;
    if (ibegin==iend)
        ST[root].val = A[ibegin];
    else
    {
        int mid = (ibegin+iend)/2;
        build(2*root,ibegin,mid);
        build(2*root+1,mid+1,iend);
        ST[root].val = operation(ST[root*2].val,ST[root*2+1].val);
    }
}
void push_down(int root,int l)
{
    if (ST[root].addmark == 0) return;
    long long addmark = ST[root].addmark;
    ST[root*2].addmark+=addmark;
    ST[root*2+1].addmark+=addmark;
    change(root*2,addmark,l-l/2);
    change(root*2+1,addmark,l/2);
    ST[root].addmark = 0;
}
long long query(int root,int ibegin,int iend,int qbegin,int qend)
{
    if (ibegin > qend || iend < qbegin)
        return 0;//
    if (ibegin>=qbegin&&iend<=qend)
        return ST[root].val;
    push_down(root,iend-ibegin+1);
    int mid = (ibegin+iend)/2;
    return operation(query(root*2,ibegin,mid,qbegin,qend),query(root*2+1,mid+1,iend,qbegin,qend));
}
void updata(int root,int ibegin,int iend,int qbegin,int qend,long long addmark)
{
    if (ibegin > qend || iend < qbegin)
        return ;//
    if (ibegin>=qbegin&&iend<=qend)
        {
            ST[root].addmark+=addmark;
            change(root,addmark,iend-ibegin+1);
            return;
        }
    push_down(root,iend-ibegin+1);
    int mid = (ibegin+iend)/2;
    updata(root*2,ibegin,mid,qbegin,qend,addmark);
    updata(root*2+1,mid+1,iend,qbegin,qend,addmark);
    ST[root].val = operation(ST[root*2].val,ST[root*2+1].val);
}
int main()
{
    int N,Q;
    while(cin >> N >>Q)
    {
        for (int i = 1;i<=N; i++)
            scanf("%lld",&A[i]);
        build(1,1,N);
        for (int i = 1;i<=Q;i++)
        {
            char c;
            scanf(" %c",&c);
            if (c=='Q')
            {
                int q1,q2;
                scanf("%d%d",&q1,&q2);
                cout << query(1,1,N,q1,q2) <<endl;
            }
            else{
                int q1,q2;
                long long q3;
                scanf("%d%d%lld",&q1,&q2,&q3);
                updata(1,1,N,q1,q2,q3);
            }
        }
    }
}
代码

直接上代码,,没什么可讲,纪念第一个手撸线段树。

posted @ 2017-03-18 23:03  HITLJR  阅读(118)  评论(0编辑  收藏  举报