http://www.lydsy.com/JudgeOnline/problem.php?id=1507
当练splay模板了,发现wjmzbmr的splay写得异常简介,学习了。orzzzzzzzzzzz!!!!!!
这个版本很好写的,比数组的好写多了。但是异常的慢啊T_T
这个版本的splay,会修改null的fa,但不影响结果,这点要记住。
#include <string> #include <cstdio> using namespace std; char strI[1024*1024+100]; struct Splay { struct node{ node *ch[2], *fa; char key; int size; node() { ch[0]=ch[1]=fa=NULL; size=key=0; } void pushup() { size=ch[0]->size+ch[1]->size+1; } bool d() { return this==fa->ch[1]; } void setc(node *c, int _d) { ch[_d]=c; c->fa=this; } }*null, *root; Splay() { null=new node; root=null; root=newnode(0); node *t=newnode(0); root->setc(t, 1); root->pushup(); } node* newnode(char key) { node *ret=new node; ret->ch[0]=ret->ch[1]=ret->fa=null; ret->key=key; ret->size=1; return ret; } void rot(node *r) { node *fa=r->fa; bool d=r->d(); fa->fa->setc(r, fa->d()); fa->setc(r->ch[!d], d); r->setc(fa, !d); fa->pushup(); if(fa==root) root=r; } void splay(node *r, node *fa) { while(r->fa!=fa) { if(r->fa->fa==fa) rot(r); else r->d()==r->fa->d()?(rot(r->fa), rot(r)):(rot(r), rot(r)); } r->pushup(); } node* sel(int k) { int s; for(node *t=root; ;) { s=t->ch[0]->size; if(s==k) return t; t=t->ch[k>s]; if(k>s) k-=s+1; } } node* getrange(int l, int r) { node *left=sel(l); splay(left, null); node *right=sel(r); splay(right, left); return right; } void insert(int at, int cur) { node *t=getrange(at, at+1); t->setc(build(0, cur), 0); t->pushup(); splay(t, null); } void remove(int at, int n) { node *t=getrange(at, at+n+1); t->setc(null, 0); t->pushup(); splay(t, null); } node* build(int l, int r) { if(l>=r) return null; int m=(l+r)>>1; node *t=newnode(strI[m]); t->setc(build(l, m), 0); t->setc(build(m+1, r), 1); t->pushup(); return t; } void print(node *r) { if(r==null) return; print(r->ch[0]); printf("%c", r->key); print(r->ch[1]); } void print(int at, int n) { node *t=getrange(at, at+n+1); print(t->ch[0]); printf("\n"); } }splay; char s[10]; int main() { int n, t, cur, at=0; scanf("%d", &n); while(n--) { scanf("%s", s); if(s[0]=='I') { scanf("%d", &t); cur=0; while(t--) { while(strI[cur]=getchar(), strI[cur]=='\n'); cur++; } splay.insert(at, cur); } else if(s[0]=='M') { scanf("%d", &at); } else if(s[0]=='D') { scanf("%d", &t); splay.remove(at, t); } else if(s[0]=='G') { scanf("%d", &t); splay.print(at, t); } else if(s[0]=='P') --at; else if(s[0]=='N') ++at; } return 0; }