[AHOI 2006][BZOJ 1269]文本编辑器editor
好吧,我承认这是我用来刷随笔数的喵~
这是一道 splay 裸题,但还是有想本傻 X 一样根本不会写 splay 的,于是乎又用 treap 水过了
splay 的常数我还是知道的,所以真是不知道那些 500ms 的人都是怎么跑出来的,跪求大爷指导
近期要学一下可持久化的 AVL 和尝试把 treap 的代码非递归化模板化(话说我真的不知道原始的 treap 怎么写了)
写完后也会发出来的喵~
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 const int size=4500000; 5 const int inf=0x7FFFFFFF; 6 7 template <class type> 8 inline void swap(type & a, type & b) 9 {type t=a; a=b; b=t;} 10 11 namespace treap 12 { 13 struct node 14 { 15 char ch; int size; 16 int weight; 17 bool rev; 18 node * left, * right; 19 inline node():size(0) {left=right=this;} 20 inline void pushdown() {if (rev) swap(left, right), left->rev^=1, right->rev^=1, rev=0;} 21 inline void maintain() {size=left->size+right->size+1;} 22 }; 23 node * null=new node(); 24 node MEM[size], * PORT=MEM; 25 26 inline node * newnode(char ch, int size) 27 { 28 node * ret=PORT++; 29 ret->ch=ch; ret->size=size; 30 ret->rev=0; 31 ret->left=ret->right=null; 32 return ret; 33 } 34 node * newtreap(char * s, int l, int w) 35 { 36 if (!l) return null; 37 node * ret=newnode(s[l>>1], l); 38 ret->weight=rand()%w+1; 39 if (l==1) return ret; 40 ret->left=newtreap(s, l>>1, ret->weight); 41 ret->right=newtreap(s+(l>>1)+1, l-(l>>1)-1, ret->weight); 42 return ret; 43 } 44 void split(node * t, int k, node *& l, node *& r) 45 { 46 if (t==null) l=r=null; 47 else 48 { 49 t->pushdown(); 50 if (t->left->size<k) 51 { 52 l=t; 53 split(t->right, k-t->left->size-1, t->right, r); 54 l->maintain(); 55 } 56 else 57 { 58 r=t; 59 split(t->left, k, l, t->left); 60 r->maintain(); 61 } 62 } 63 } 64 node * merge(node * l, node * r) 65 { 66 if (l==null) return r; 67 if (r==null) return l; 68 if (l->weight>r->weight) 69 { 70 l->pushdown(); 71 l->right=merge(l->right, r); 72 l->maintain(); 73 return l; 74 } 75 else 76 { 77 r->pushdown(); 78 r->left=merge(l, r->left); 79 r->maintain(); 80 return r; 81 } 82 } 83 } 84 85 int N, mouse; 86 char str[size]; 87 treap::node * root=treap::newnode(' ', 1); 88 void print(treap::node * ); 89 inline void insert(char * , int); 90 inline void remove(int); 91 inline void rotate(int); 92 inline char get(); 93 94 int main() 95 { 96 int x; 97 98 scanf("%d", &N); mouse=0; 99 root->weight=rand(); 100 for ( ;N;N--) 101 { 102 scanf("%s", str); 103 if (str[0]=='G') putchar(get()), putchar('\n'); 104 else if (str[0]=='M') scanf("%d", &x), mouse=x; 105 else if (str[0]=='P' && mouse) mouse--; 106 else if (str[0]=='N' && mouse<root->size) mouse++; 107 else if (str[0]=='R') scanf("%d", &x), rotate(x); 108 else if (str[0]=='D') scanf("%d", &x), remove(x); 109 else 110 { 111 scanf("%d", &x); 112 do gets(str); while (!strlen(str)); 113 insert(str, x); 114 } 115 } 116 117 return 0; 118 } 119 inline void insert(char * s, int l) 120 { 121 treap::node * L, * M, * R; 122 treap::split(root, mouse, L, R); 123 M=treap::newtreap(s, l, inf); 124 L=treap::merge(L, M); 125 root=treap::merge(L, R); 126 } 127 inline void remove(int l) 128 { 129 treap::node * L, * M, * R; 130 treap::split(root, mouse, L, R); 131 treap::split(R, l, M, R); 132 root=treap::merge(L, R); 133 } 134 inline void rotate(int l) 135 { 136 treap::node * L, * M, * R; 137 treap::split(root, mouse, L, R); 138 treap::split(R, l, M, R); 139 M->rev^=1; 140 L=treap::merge(L, M); 141 root=treap::merge(L, R); 142 } 143 inline char get() 144 { 145 treap::node * i=root; 146 int k=mouse+1; 147 for ( ; ; ) 148 { 149 i->pushdown(); 150 if (i->left->size+1==k) return i->ch; 151 if (i->left->size+1<k) 152 { 153 k-=i->left->size+1; 154 i=i->right; 155 } 156 else 157 i=i->left; 158 } 159 }