hdu 4699 Editor(Splay)
2013-09-02 01:22
337 查看
题意:对一个数列进行操作,光标位置后面插入一个权值为x的数,删除光标前的那个数,光标左移一位,光标右移一位,求到k位置的最大的前缀和。
Splay在比赛的时候写得太Navie,T了整场。
左移和右移的操作就不说了,删除点的操作是,直接把第pos个点旋转成根结点,然后把这个点删除,将左右两个儿子(如果有)合并成一棵新的树。插入的时候,将pos个点旋转成根结点,然后在根和根的右儿子之间插入这个点。
同时维护sum(区间和),和mx(表示以x为根结点的最大前缀和),就可以解决这道题了。
Splay在比赛的时候写得太Navie,T了整场。
左移和右移的操作就不说了,删除点的操作是,直接把第pos个点旋转成根结点,然后把这个点删除,将左右两个儿子(如果有)合并成一棵新的树。插入的时候,将pos个点旋转成根结点,然后在根和根的右儿子之间插入这个点。
同时维护sum(区间和),和mx(表示以x为根结点的最大前缀和),就可以解决这道题了。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define LL(x) (ch[x][0]) #define RR(x) (ch[x][1]) #define Kt(x) (ch[ ch[Rt][1] ][0]) #define INF (1<<30) const int N=1e6+5; struct SplayTree { int Rt,top; int ch [2],pre ,sz ; int key ,sum ,mx ,pos; void init() { top=Rt=pos=0; pre[0]=LL(0)=RR(0)=sz[0]=0; } inline void Link(int x,int y,int f) { ch[y][f]=x; pre[x]=y; } inline void Rotate(int x,int f) { int y=pre[x],z=pre[y]; PushDown(y); PushDown(x); Link(ch[x][f],y,!f); Link(x,z,RR(z)==y); Link(y,x,f); PushUp(y); } inline void Splay(int x,int goal) { while(pre[x]!=goal) { int y=pre[x],z=pre[y]; int cx=(LL(y)==x),cy=(LL(z)==y); if(z==goal) Rotate(x,cx); else { if(cx==cy) Rotate(y,cy); else Rotate(x,cx); Rotate(x,cy); } } PushUp(x); if(goal==0) Rt=x; } inline void Select(int K,int goal) { int x=Rt; PushDown(x); while(1) { if(sz[LL(x)]>=K) x=LL(x); else if(sz[LL(x)]+1==K) break; else K-=sz[LL(x)]+1,x=RR(x); PushDown(x); } Splay(x,goal); } inline int Join(int r1,int r2) { if(!r1) { if(!r2) return 0; pre[r2]=0; return r2; } int x=r1; while(RR(x)) x=RR(x); Splay(x,Rt); Link(r2,x,1); Rt=x; pre[x]=0; PushUp(x); return x; } void addNode(int valu,int &x,int f) { x=top++; pre[x]=f; LL(x)=RR(x)=0; key[x]=valu; } void PushDown(int x) {} void PushUp(int x) { sz[x]=1; sum[x]=key[x]; if(LL(x)) sum[x]+=sum[LL(x)],sz[x]+=sz[LL(x)]; if(RR(x)) sum[x]+=sum[RR(x)],sz[x]+=sz[RR(x)]; if(LL(x)) { mx[x]=max(mx[LL(x)],sum[LL(x)]+key[x]); if(RR(x)) mx[x]=max(mx[x],sum[LL(x)]+key[x]+mx[RR(x)]); } else { mx[x]=key[x]; if(RR(x)) mx[x]=max(mx[x],key[x]+mx[RR(x)]); } } inline void Insert() { int valu; scanf("%d",&valu); int x=++top; sz[x]=1; pre[x]=0; LL(x)=RR(x)=0; key[x]=valu; sum[x]=0; mx[x]=-INF; if(pos==0) { Link(Rt,x,1); Rt=x; PushUp(Rt); } else { Select(pos,0); int tmp=RR(Rt); Link(x,Rt,1); Link(tmp,x,1); PushUp(x); PushUp(Rt); } pos++; } inline void Delete() { if(pos==0) return; Select(pos,0); Rt=Join(LL(Rt),RR(Rt)); if(Rt) PushUp(Rt); pos--; } void Query() { int K; scanf("%d",&K); K=min(K,sz[Rt]); Select(K,0); int ans=-1; if(LL(Rt)) ans=max(mx[LL(Rt)],sum[LL(Rt)]+key[Rt]); else ans=key[Rt]; printf("%d\n",ans); } inline void shift(int flag) { if(flag==0) { if(pos>0) pos--; } else { if(pos<sz[Rt]) pos++; } } void Debug(){ printf("Rt:%d\n",Rt); travel(Rt); } void travel(int x) { if(x==0) return; travel(LL(x)); printf("node:%d,pre:%d,sz:%d,lson:%d,rson:%d,key:%d,sum:%d,mx:%d\n", x,pre[x],sz[x],LL(x),RR(x),key[x],sum[x],mx[x]); travel(RR(x)); } }spt; int main() { int n; while(scanf("%d",&n)!=EOF) { spt.init(); for(int i=0;i<n;i++) { char op[100]; scanf("%s",op); if(op[0]=='L') spt.shift(0); else if(op[0]=='R') spt.shift(1); else if(op[0]=='I') spt.Insert(); else if(op[0]=='D') spt.Delete(); else spt.Query(); // spt.Debug(); } } return 0; }
相关文章推荐
- Hdu 4699 Editor(Splay)
- 2013 多校第九场 hdu 4699 Editor(vector OR splay tree)
- hdu 4699 Editor 双栈维护最长前缀
- HDU 4699 Editor (双栈)
- HDU 4699 Editor (栈的使用,模拟)
- hdu 4699 Editor
- HDU-4699 Editor 数据结构维护
- HDU 4699 Editor( stack)
- hdu 4699 Editor (巧用两个栈)
- hdu 4699 Editor 模拟栈
- hdu 4699 Editor 伸展树 treap复习
- HDU 4699 Editor(双向链表)
- HDU 4699 Editor
- HDU 4699 Editor 树状数组
- HDU 4699 Editor (2013多校10,1004题)
- hdu 4699 Editor(单调栈)
- hdu 4699 Editor 模拟
- hdu 4699 Editor 多校第十场 (模拟)
- HDU 1890 UVaLive 3961 - Robotic Sort (Splay)
- hdu 4699 双栈模拟