[hdu 4348]区间修改区间查询可持久化线段树

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4348

一开始把lazy标记给push_down了,后来发现这样会让持久化变乱,然后想到不用push_down也可以统计和,改写之后就过了。

#include<bits/stdc++.h>
using namespace std;

const int maxn=100005;
int a[maxn];
int rt[maxn];
int ts;
int n;

struct Node
{
    int lson,rson;
    long long val,lz;
}node[30*maxn];
int tot;

void push_up(int i)
{
    node[i].val=node[node[i].lson].val+node[node[i].rson].val;
}

//void push_down(int i)
//{
//    if (node[i].lz==0) return;
//    int ls=node[i].lson;
//    int rs=node[i].rson;
//    node[ls].lz+=node[i].lz;
//    node[rs].lz+=node[i].lz;
//    node[ls].val+=node[i].lz*node[ls].len;
//    node[rs].val+=node[i].lz*node[rs].len;
//    node[i].lz=0;
//}

int build(int l,int r)
{
    int th=++tot;
    node[th].lz=0;
    if (l==r) node[th].val=a[l];
    else
    {
        int mid=(l+r)/2;
        node[th].lson=build(l,mid);
        node[th].rson=build(mid+1,r);
        push_up(th);
    }
    return th;
}

int rebuild(int l,int r,int x,int i,int nowl,int nowr)
{
    int th=++tot;
    node[th].val=node[i].val;
    node[th].lson=node[i].lson;
    node[th].rson=node[i].rson;
    node[th].lz=node[i].lz;
    if (l==nowl&&r==nowr)
    {
        node[th].lz+=x;
        node[th].val+=x*(nowr-nowl+1);
    }
    else
    {
        int mid=(nowl+nowr)/2;
        if (r<=mid) node[th].lson=rebuild(l,r,x,node[i].lson,nowl,mid);
        else if (l>mid) node[th].rson=rebuild(l,r,x,node[i].rson,mid+1,nowr);
        else
        {
            node[th].lson=rebuild(l,mid,x,node[i].lson,nowl,mid);
            node[th].rson=rebuild(mid+1,r,x,node[i].rson,mid+1,nowr);
        }
        push_up(th);
        node[th].val+=node[th].lz*(nowr-nowl+1);
    }
    return th;
}

void insert(int l,int r,int x)
{
    rt[++ts]=rebuild(l,r,x,rt[ts-1],1,n);
}

long long querysum(int l,int r,int i,int nowl,int nowr)
{
    if (nowl==l&&nowr==r) return node[i].val;
    int mid=(nowl+nowr)/2;
//    push_down(i);
    long long res=0;
    if (l>=nowl&&r<=nowr) res+=node[i].lz*(r-l+1);
    else if (l<nowl&&r>=nowl&&r<=nowr) res+=node[i].lz*(r-nowl+1);
    else if (r>nowr&&l>=nowl&&l<=nowr) res+=node[i].lz*(nowr-l+1);
    else if (l<nowl&&r>nowr) res+=node[i].lz*(nowr-nowl+1);
    if (r<=mid) res+=querysum(l,r,node[i].lson,nowl,mid);
    else if (l>mid) res+=querysum(l,r,node[i].rson,mid+1,nowr);
    else res+=querysum(l,mid,node[i].lson,nowl,mid)+querysum(mid+1,r,node[i].rson,mid+1,nowr);
    return res;
}

long long query(int l,int r,int t)
{
    return querysum(l,r,rt[t],1,n);
}

int main()
{
    int m;
    while (~scanf("%d%d",&n,&m))
    {
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        ts=tot=0;
        rt[0]=build(1,n);
        while (m--)
        {
            char s[5];
            scanf("%s",s);
            if (s[0]=='C')
            {
                int l,r,d;
                scanf("%d%d%d",&l,&r,&d);
                insert(l,r,d);
            }
            else if (s[0]=='Q')
            {
                int l,r;
                scanf("%d%d",&l,&r);
                printf("%I64d\n",query(l,r,ts));
            }
            else if (s[0]=='H')
            {
                int l,r,t;
                scanf("%d%d%d",&l,&r,&t);
                printf("%I64d\n",query(l,r,t));
            }
            else
            {
                int t;
                scanf("%d",&t);
                ts=t;
            }
        }
    }
    return 0;
}

 

posted @ 2017-08-16 14:55  ACMsong  阅读(938)  评论(0编辑  收藏  举报