SPOJ TTM To The Moon 主席树的区间更新与查询

来源:互联网 发布:打卡机数据恢复 编辑:程序博客网 时间:2024/05/16 16:05

首先要吐槽一下,区间更新的主席树的内存开销已经瞬间爆炸了。。n,m <= 10W的数据所需内存就已经顶到200M了OTZ。。。

首先主席树所需要的lazy与普通线段树的lazy无差。主席树需要另开一个标记来判断当前节点是否是前一层的节点,如果是就在pushdown的时候分配一个新的。

HDU已经MLE成狗了。不过可持久化的BIT 貌似可过,线段树被卡系数了OTZ。。。

#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <cmath>#include <algorithm>#include <string>#define LL long long#define EPS (1e-8)#define INF  0x3f3f3fusing namespace std;const int MAXN = 400010;const int MAXLOG = 17;int lson[MAXN*MAXLOG],rson[MAXN*MAXLOG];bool ml[MAXN*MAXLOG],mr[MAXN*MAXLOG];LL lazy[MAXN*MAXLOG];LL sum[MAXN*MAXLOG];int ctRoot[MAXN];int ctTop;int Time;int num[MAXN];int CreatNewNode(){    lson[ctTop] = -1;    rson[ctTop] = -1;    ml[ctTop] = false;    mr[ctTop] = false;    lazy[ctTop] = 0;    sum[ctTop] = 0;    return ctTop++;}LL InitZeroLayer(int L,int R,int &root){    root = CreatNewNode();    ml[root] = true,mr[root] = true;    if(L == R)        return sum[root] = num[L];    int mid = (L+R)>>1;    return sum[root] = InitZeroLayer(L,mid,lson[root]) + InitZeroLayer(mid+1,R,rson[root]);}void InitChairTree(int n){    memset(ctRoot,-1,sizeof(ctRoot));    ctTop = 0;    InitZeroLayer(1,n,ctRoot[0]);}void PushUp(int root){    sum[root] = sum[lson[root]] + sum[rson[root]];}void Update(int L,int R,int l,int r,LL data,int &root,int pre){    if(root == -1)    {        root = CreatNewNode();        lson[root] = lson[pre];        rson[root] = rson[pre];        lazy[root] = lazy[pre];        sum[root] = sum[pre];    }    // cout<<"&&& L = "<<L<<" R = "<<R<<" sum = "<<sum[root]<<endl;    if(L == l && R == r)    {        sum[root] += data*(r-l+1);        lazy[root] += data;   //     cout<<"L = "<<L<<" R = "<<R<<" sum = "<<sum[root]<<endl;        return ;    }    int mid = (L+R)>>1;    if(lazy[root])    {        if(ml[root] == false)            ml[root] = true,lson[root] = -1;        if(mr[root] == false)            mr[root] = true,rson[root] = -1;        Update(L,mid,L,mid,lazy[root],lson[root],lson[pre]);        Update(mid+1,R,mid+1,R,lazy[root],rson[root],rson[pre]);        lazy[root] = 0;    }    if(r <= mid)    {        if(ml[root] == false)            ml[root] = true,lson[root] = -1;        Update(L,mid,l,r,data,lson[root],lson[pre]);    }    else if(mid < l)    {        if(mr[root] == false)            mr[root] = true,rson[root] = -1;        Update(mid+1,R,l,r,data,rson[root],rson[pre]);    }    else    {        if(ml[root] == false)            ml[root] = true,lson[root] = -1;        Update(L,mid,l,mid,data,lson[root],lson[pre]);        if(mr[root] == false)            mr[root] = true,rson[root] = -1;        Update(mid+1,R,mid+1,r,data,rson[root],rson[pre]);    }    PushUp(root);}LL Query(int L,int R,int l,int r,int root){    if(L == l && R == r)        return sum[root];    int mid = (L+R)>>1;    if(lazy[root])    {        int tl = lson[root],tr = rson[root];        if(ml[root] == false)            ml[root] = true,lson[root] = -1;        if(mr[root] == false)            mr[root] = true,rson[root] = -1;        Update(L,mid,L,mid,lazy[root],lson[root],tl);        Update(mid+1,R,mid+1,R,lazy[root],rson[root],tr);        lazy[root] = 0;    }    if(r <= mid)        return Query(L,mid,l,r,lson[root]);    if(mid < l)        return Query(mid+1,R,l,r,rson[root]);    return Query(L,mid,l,mid,lson[root]) + Query(mid+1,R,mid+1,r,rson[root]);}int main(){    int i,n,m,l,r,d,t;    char op[4];    while(scanf("%d %d",&n,&m) != EOF)    {        for(i = 1;i <= n; ++i)            scanf("%d",&num[i]);        InitChairTree(n);        Time = 0;        while(m--)        {            scanf("%s",op);            if(op[0] == 'B')            {                scanf("%d",&t);                for(i = t+1;i <= Time; ++i)                    ctRoot[i] = -1;                Time = t;            }            else if(op[0] == 'C')            {                scanf("%d %d %d",&l,&r,&d);                Time++;                Update(1,n,l,r,d,ctRoot[Time],ctRoot[Time-1]);            }            else if(op[0] == 'Q')            {                scanf("%d %d",&l,&r);                printf("%lld\n",Query(1,n,l,r,ctRoot[Time]));            }            else            {                scanf("%d %d %d",&l,&r,&t);                printf("%lld\n",Query(1,n,l,r,ctRoot[t]));            }        }    }    return 0;}

0 0
原创粉丝点击