标签:
首先要吐槽一下,区间更新的主席树的内存开销已经瞬间爆炸了。。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 0x3f3f3f using 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; }
SPOJ TTM To The Moon 主席树的区间更新与查询
标签:
原文地址:http://blog.csdn.net/zmx354/article/details/45193881