1. 程式人生 > >[Luogu 2596] ZJOI2006 書架

[Luogu 2596] ZJOI2006 書架

num else top cas eap main www bottom 省選

[Luogu 2596] ZJOI2006 書架

<題目鏈接>


第一次指針寫 FHQ_Treap(省選噩夢數據結構)AC 啦!

省選試機寫它,緊張過度失敗了。

省選 Day 1 考場寫它,寫掛了。

省選 Day 1 當晚認真復習它,結果 Day 2 並不考。

於是省選後用指針寫出來了,開心qwq。

這個題嘛,記錄一下每個點對應的指針,順便維護一下父節點,每次需要的時候,就可以一路向上找到這個點的位置。

就這麽簡單的呀qwq

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <stack>
using std::stack; const int MAXN=80010; int n,m,pos[MAXN]; class FHQ_Treap { public: FHQ_Treap(void) { srand(19260817); rt=nullptr; } ~FHQ_Treap(void) { delete rt; } void Init(void) { Build(rt); } void
Top(void) { int x; Node *l,*r,*t; scanf("%d",&x); x=Rank(pos[x]); Split(rt,x-1,l,r),Split(r,1,t,r),Merge(l,t,l),Merge(rt,l,r); } void Bottom(void) { int x; Node *l,*r,*t; scanf("
%d",&x); x=Rank(pos[x]); Split(rt,x-1,l,r),Split(r,1,t,r),Merge(r,r,t),Merge(rt,l,r); } void Insert(void) { int x,k; scanf("%d %d",&x,&k); if(!k) return; Node *l,*r,*p,*q; x=Rank(pos[x]); if(k==-1) Split(rt,x-2,l,r); else Split(rt,x-1,l,r); Split(r,1,p,r),Split(r,1,q,r),Merge(l,l,q),Merge(r,p,r),Merge(rt,l,r); } void Ask(void) { int x; scanf("%d",&x); printf("%d\n",Rank(pos[x])-1); } void Query(void) { int x; Node *l,*r,*t; scanf("%d",&x); Split(rt,x-1,l,r),Split(r,1,t,r); printf("%d\n",t->v); Merge(l,l,t),Merge(rt,l,r); } private: struct Node { int v,p,num,size; Node *ft,*c[2]; Node(int v=0,int p=0,int num=0,int size=0):v(v),p(p),num(num),size(size) { ft=c[0]=c[1]=nullptr; } ~Node(void) { if(c[0]!=nullptr) delete c[0]; if(c[1]!=nullptr) delete c[1]; } }*rt,*pos[MAXN]; void Update(Node *i) { i->size=1,pos[i->v]=i; if(i->c[0]!=nullptr) { i->size+=i->c[0]->size; i->c[0]->ft=i; } if(i->c[1]!=nullptr) { i->size+=i->c[1]->size; i->c[1]->ft=i; } } void Build(Node *&k) { stack<Node *> st; for(int i=1,t;i<=n;++i) { scanf("%d",&t); Node *x=new Node(t,rand(),i,1); pos[t]=x,k=nullptr; while(!st.empty() && x->p>st.top()->p) Update(k=st.top()),st.pop(); if(!st.empty()) st.top()->c[1]=x; x->c[0]=k,st.push(x); } while(!st.empty()) Update(k=st.top()),st.pop(); } void Split(Node *i,int x,Node *&l,Node *&r) { if(i==nullptr) { l=r=nullptr; return; } int t=(i->c[0]!=nullptr ? i->c[0]->size : 0)+1; if(x<t) Split((r=i)->c[0],x,l,i->c[0]); else Split((l=i)->c[1],x-t,i->c[1],r); Update(i); } void Merge(Node *&i,Node *l,Node *r) { if(l==nullptr || r==nullptr) { i=l!=nullptr ? l : r; return; } if(l->p>r->p) Merge((i=l)->c[1],l->c[1],r); else Merge((i=r)->c[0],l,r->c[0]); Update(i); } int Rank(Node *i) { int ans=(i->c[0]!=nullptr ? i->c[0]->size : 0)+1; while(i->ft!=nullptr) { if(i==i->ft->c[1]) ans+=(i->ft->c[0]!=nullptr ? i->ft->c[0]->size : 0)+1; i=i->ft; } return ans; } }*T=new FHQ_Treap; int main(int argc,char *argv[]) { scanf("%d %d",&n,&m); T->Init(); for(int i=1;i<=m;++i) { char str[10]; scanf("\n%s",str); switch(str[0]) { case ‘T‘: T->Top(); break; case ‘B‘: T->Bottom(); break; case ‘I‘: T->Insert(); break; case ‘A‘: T->Ask(); break; case ‘Q‘: T->Query(); break; } } delete T; return 0; }

謝謝閱讀。

[Luogu 2596] ZJOI2006 書架