hdu 4453 Looploop(splay)
2015-01-14 16:00
351 查看
hdu4454Looploop
一看到有旋转操作就splay了
做两个lazy标记: flip(旋转), add(增加)
六种操作
增加,删除,旋转,插入,移动,查询
1.add增加:add(x) 对前k2个数字增加x
将从箭头指向位置开始前k2个节点从树中分离,分离出来的根节点add+x,再将两棵树合并
2.reverse旋转: 将前k1个数字颠倒过来
将从箭头指向位置开始前k1个节点从书中分离,分离出来的根节点flip=1, 再将两棵树合并
3.insert插入: insert(x) 在箭头指向位置的后面插入一个x
将指向位置伸展为树根,那么其他所有的节点都在根的右孩子,在根与根的右孩子前插入x即可,节点数n+1
4.delete删除:将箭头指向位置的数字删除,箭头顺时针移动一个位置(右移/后移)
将指向位置伸展为树根,那么其他所有的节点都在根的右孩子,将树根删除,将原树根右孩子设为新根,节点数n-1
5.move移动:move(x), x=1箭头逆时针移动(左移/前移),x=2箭头顺时针移动(右移/后移)
x=1 将n位置的节点从树中分离,将原根设为其右孩子:root=splay(n),root->child[1]=splay(1);
x=2与此类似
6.query查询:输出箭头指向位置的数字
将指向位置伸展为树根,root=splay(1),output:root->value
===========================================================
刚开始new节点,果断超时,后来开了数组,newnode(int) 替换new node(int)
最后发现cnt出了问题,竟然sb的build之后cnt=0.。。
代码如下: 343ms
一看到有旋转操作就splay了
做两个lazy标记: flip(旋转), add(增加)
六种操作
增加,删除,旋转,插入,移动,查询
1.add增加:add(x) 对前k2个数字增加x
将从箭头指向位置开始前k2个节点从树中分离,分离出来的根节点add+x,再将两棵树合并
2.reverse旋转: 将前k1个数字颠倒过来
将从箭头指向位置开始前k1个节点从书中分离,分离出来的根节点flip=1, 再将两棵树合并
3.insert插入: insert(x) 在箭头指向位置的后面插入一个x
将指向位置伸展为树根,那么其他所有的节点都在根的右孩子,在根与根的右孩子前插入x即可,节点数n+1
4.delete删除:将箭头指向位置的数字删除,箭头顺时针移动一个位置(右移/后移)
将指向位置伸展为树根,那么其他所有的节点都在根的右孩子,将树根删除,将原树根右孩子设为新根,节点数n-1
5.move移动:move(x), x=1箭头逆时针移动(左移/前移),x=2箭头顺时针移动(右移/后移)
x=1 将n位置的节点从树中分离,将原根设为其右孩子:root=splay(n),root->child[1]=splay(1);
x=2与此类似
6.query查询:输出箭头指向位置的数字
将指向位置伸展为树根,root=splay(1),output:root->value
===========================================================
刚开始new节点,果断超时,后来开了数组,newnode(int) 替换new node(int)
node lk[maxn]; int cnt; node* newnode(int v) { lk[cnt]=node(v); return lk+cnt++; }
build(root, 1, N); cnt=0;一直是运行出错调试了一上午 = = 。。。。。。。飙泪
最后发现cnt出了问题,竟然sb的build之后cnt=0.。。
代码如下: 343ms
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; const int maxn = 2e5+5; int N, M, K1, K2; int hdu[maxn]; struct node { node *child[2]; int size; int value; int flip; int add; node (); node(int); void pushup(); void pushdown(); int rank(); int cmp(int k); }null, *root, lk[maxn]; int cnt; node* newnode(int v) {lk[cnt]=node(v); return lk+cnt++; } int node:: cmp(int k) { if(k==rank()) return -1; return k < rank() ? 0 : 1; } int node:: rank() { return child[0]->size+1; } void node:: pushdown() {
if(flip) { swap(child[0], child[1]); child[0]->flip^=1; child[1]->flip^=1; flip=0; } if(add) { value+=add; child[0]->add+=add; child[1]->add+=add; add=0; } } void node:: pushup() { size=child[0]->size+child[1]->size+1; } node:: node() { child[0]=child[1]=&null; size=0; flip=0; add=0; } node:: node(int _value): value(_value) { child[0]=child[1]=&null; size=1; flip=0; add=0; } void rotate(node*&o, int d) { o->pushdown(); node *t=o->child[d]; t->pushdown(); o->child[d]=t->child[d^1]; t->child[d^1]=o; o->pushup(); o=t; o->pushup(); } void splay(node*& o, int k) { o->pushdown(); int d=o->cmp(k); if(~d) { if(d) splay(o->child[d], k-o->rank()); else splay(o->child[d], k); rotate(o, d); } } void build(node*&o, int l ,int r) { int m= (l+r)>>1; o=newnode(hdu[m]); if(m>l) build(o->child[0], l, m-1); if(m<r) build(o->child[1], m+1, r); o->pushup(); } void add(int x) { splay(root, K2); root->value+=x; root->child[0]->add+=x; } void reverse() { splay(root, K1); node*temp=root->child[1]; root->child[1]=&null; root->pushup(); root->flip=1; root->pushdown(); splay(root, K1); root->child[1]=temp; root->pushup(); } void insert(int x) { splay(root, 1); node *temp=newnode(x); temp->child[1]=root->child[1]; temp->pushup(); root->child[1]=temp; root->pushup(); N++; } void remove() { splay(root, 1); node *temp=root->child[1]; root=temp; root->pushdown(); N--; } void move(int x) { if(x==1) { splay(root, N); node *temp = root->child[0]; root->child[0]=&null; temp->pushdown(); splay(temp, 1); root->child[1]=temp; root->pushup(); } else { splay(root, 1); node *temp = root->child[1]; root->child[1]=&null; temp->pushdown(); splay(temp, N-1); root->child[0]=temp; root->pushup(); } } int main() { int kase=1; while(cin>>N>>M>>K1>>K2 && N|M|K1|K2) { for(int i=1;i<=N;i++) scanf("%d", hdu+i); cnt=0; build(root, 1, N); printf("Case #%d:\n", kase++); while(M--) { char op1[10]; scanf("%s", op1); if(!strcmp(op1, "add")) { int op2; scanf("%d", &op2); add(op2); } else if(!strcmp(op1, "reverse")) { reverse(); } else if(!strcmp(op1, "insert")) { int op2; scanf("%d", &op2); insert(op2); } else if(!strcmp(op1, "delete")) { remove(); } else if(!strcmp(op1, "move")) { int op2; scanf("%d", &op2); move(op2); } else { splay(root, 1); printf("%d\n", root->value); } } } return 0; }
相关文章推荐
- hdu 4453 Looploop(splay基本操作)
- HDU-4453 Looploop(Splay树) 4000
- hdu4453 Looploop 2012年杭州现场赛 Splay
- hdu 4453 Looploop 伸展树splay
- hdu-4453-Looploop-splay
- 【HDU】4453 Looploop 【splay】
- Hdu 4453 Looploop(环上的Splay操作)
- hdu 4453 Looploop(Splay或者三个双端队列)
- 【HDU 4453】 Looploop(Splay)
- HDU 4453 Looploop (Treap)
- hdu4453 Splay
- HDU 4453 Looploop(SplayTree)
- HDU 4453 Looploop (splay tree)
- 【splay】hdu 4453 2012杭州赛区A题
- HDU 4453 (splay 插入删除翻转区间加单点查)
- hdu 4453 Looploop (伸展树)
- hdu 4453 splay
- hdu 4453 Looploop(伸展树)
- hdu 4453 splay
- HDU 4453 Looploop (2012年杭州赛区现场赛A题)