[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不成反被艹系列

 

你可能感兴趣的:(editor)