poj 3468 线段树模板题

#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
#define Lson rt<<1
#define Rson rt<<1|1
//这里写的和学长不一样,我遵从是叶子结点的四倍定义数组,学长定义的是 1e5+5<<1,
const int Maxn=1e5+5;
struct node
{
    int mid, len, L, R;
    __int64 e, sum;
} a[Maxn<<2];//第一次提交runtime了,我发现是数组开小了,我发现我定义的是叶子结点的二倍,粗心了。
//不过还是基础知识不牢固,毕竟我只是记住了结论,但不知从何而推来。
__int64 x;

void Buildsegtree(int rt, int L, int R);//建立
void pushdown(int rt);//下推
__int64 Query(int rt, int L, int R);//查询
void Update(int rt, int L, int R, int e);//更新

int main()
{
    int n, m, a, b, c;
    scanf("%d%d", &n, &m);
    Buildsegtree(1, 1, n);
    while(m--)
    {
        char s[3];
        scanf("%s", s);
        if(s[0]=='Q')
        {
            scanf("%d%d", &a, &b);
            printf("%I64d\n", Query(1, a, b));
        }
        else
        {
            scanf("%d%d%d", &a, &b, &c);
            Update(1, a, b, c);
        }
    }
    return 0;
}
void Buildsegtree(int rt, int L, int R)//建立
{
    a[rt].L=L;
    a[rt].R=R;
    a[rt].e=0;//这点没写,之后核对的时候才发现
    a[rt].mid=(L+R)>>1;
    a[rt].len=(R-L)+1;//我吧if语句写在了这些赋值语句之前,不知道可以不,
//反正改了过来,不过我觉得写前面后面都一样,毕竟它的叶子节点没有左孩子和有孩子了
//之后把他俩换了换位置发现不行
    if(L==R)
    {
        scanf("%I64d", &x);
        a[rt].sum=x;
        return;
    }
    Buildsegtree(Lson, L, a[rt].mid);
    Buildsegtree(Rson, a[rt].mid+1, R);
    a[rt].sum=a[Lson].sum+a[Rson].sum;
}

void pushdown(int rt)//下推
{
    a[Lson].sum+=a[rt].e*a[Lson].len;
    a[Lson].e+=a[rt].e;
    a[Rson].sum+=a[rt].e*a[Rson].len;
    a[Rson].e+=a[rt].e;
    a[rt].e=0;
}
__int64 Query(int rt, int L, int R)
{
    if(a[rt].L==L&&a[rt].R==R)
    {
        return a[rt].sum;
    }

    pushdown(rt);

    if(R<=a[rt].mid)
        Query(Lson, L, R);
    else if(L>a[rt].mid)
        Query(Rson, L, R);
    else
    {
        __int64 Lsum=Query(Lson, L, a[rt].mid);
        __int64 Rsum=Query(Rson, a[rt].mid+1, R);

        return Lsum+Rsum;
    }
}
void Update(int rt, int L, int R, int e)
{
//少写了这一步
    a[rt].sum+=(R-L+1)*e;
    if(a[rt].L==L&&a[rt].R==R)
    {
        a[rt].e+=e;
        return;
    }

    pushdown(rt);

    if(R<=a[rt].mid)
        Update(Lson, L, R, e);
    else if(L>a[rt].mid)
        Update(Rson, L, R, e);
    else
    {
        Update(Lson, L, a[rt].mid, e);
        Update(Rson, a[rt].mid+1, R, e);
    }
}

 

posted @ 2015-08-03 16:53  花开须臾  阅读(164)  评论(0编辑  收藏  举报