dyllalala

导航

[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 }
本傻装B不成反被艹系列

 

posted on 2014-08-09 16:08  dyllalala  阅读(217)  评论(0编辑  收藏  举报