POJ 3580 SuperMemo
2011-07-26 11:23
281 查看
http://poj.org/problem?id=3580
题目大意说给你一个数列,有区间同加一个数、区间翻转操作、区间滚动操作、删除一个数、插入一个数,查询区间最小值这些操作。
我是使用Splay乱搞的。其中revolve操作有点头疼,不过仔细观察发现,revolve l r x 其实就是交换(l,r-x)和(r-x+1,r)两个区间。
代码很长很长很长……而且跟QZ的很像很像很像……
题目大意说给你一个数列,有区间同加一个数、区间翻转操作、区间滚动操作、删除一个数、插入一个数,查询区间最小值这些操作。
我是使用Splay乱搞的。其中revolve操作有点头疼,不过仔细观察发现,revolve l r x 其实就是交换(l,r-x)和(r-x+1,r)两个区间。
代码很长很长很长……而且跟QZ的很像很像很像……
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #define INF ~0u>>1 #define NIL SPLAY #define MN 200005 using namespace std; int n,m,l,r,x,pos; char s[10]; struct SPLAYTREE{ struct NODE{ int key,minv,size,add; bool rev; NODE *left,*right,*father; NODE (){} NODE(int _key):key(_key){minv=_key,size=1,add=0,rev=false;} }SPLAY[MN],*SP,*root,*head,*tail; void init(){ SP=NIL; NIL->key=NIL->minv=INF,NIL->size=0; NIL->left=NIL->right=NIL->father=NIL; head=new(++SP)NODE(INF); head->left=head->right=head->father=NIL; tail=new(++SP)NODE(INF); tail->left=tail->right=tail->father=NIL; head->right=tail,tail->father=head,head->size++; root=head; } void pushdown(NODE *&t){ if(t->rev){ swap(t->left,t->right); t->left->rev=!t->left->rev; t->right->rev=!t->right->rev; t->rev=false; } if(t->add){ if(t->left!=NIL){ t->left->key+=t->add; t->left->minv+=t->add; t->left->add+=t->add; } if(t->right!=NIL){ t->right->key+=t->add; t->right->minv+=t->add; t->right->add+=t->add; } t->add=0; } } void update(NODE *&t){ t->size=t->left->size+t->right->size+1; t->minv=min(t->key,min(t->left->minv,t->right->minv)); } void zig(NODE *&t){ NODE *f=t->father,*r=t->right; pushdown(f->right); pushdown(t->left); pushdown(t->right); t->father=f->father; if(f==root) root=t; else{ if(f->father->left==f) f->father->left=t; else f->father->right=t; } t->right=f,r->father=f,f->father=t,f->left=r; update(f);update(t); } void zag(NODE *&t){ NODE *f=t->father,*l=t->left; pushdown(f->left); pushdown(t->left); pushdown(t->right); t->father=f->father; if(f==root) root=t; else{ if(f->father->left==f) f->father->left=t; else f->father->right=t; } t->left=f,l->father=f,f->father=t,f->right=l; update(f);update(t); } void splay(NODE *&root,NODE *&t){ pushdown(t); while(root!=t){ if(t->father==root){ if(t->father->left==t) zig(t); else zag(t); } else{ if(t->father->father->left==t->father){ if(t->father->left==t) zig(t->father),zig(t); else zag(t),zig(t); }else{ if(t->father->left==t) zig(t),zag(t); else zag(t->father),zag(t); } } } } void insert(int key,int pos){ NODE *t=new(++SP)NODE(key); t->left=t->right=t->father=NIL; NODE *r=root,*p; bool flag=false; while(pushdown(r),r!=NIL){ p=r,r->size++; if(r->left->size+1>pos)r=r->left,flag=false; else pos-=r->left->size+1,r=r->right,flag=true; } if(flag) p->right=t; else p->left=t; t->father=p; splay(root,t); } void select(NODE *&root,int pos){ NODE *r=root; while(pushdown(r),r->left->size+1!=pos){ if(r->left->size+1>pos) r=r->left; else pos-=r->left->size+1,r=r->right; } splay(root,r); } void remove(int pos){ select(root,pos); if(root->left==NIL) root=root->right; else if(root->right==NIL) root=root->left; else{ select(root->left,root->left->size); root->left->right=root->right; root->right->father=root->left; root=root->left; } root->father=NIL; update(root); } void plus(int l,int r,int a){ select(root,l); select(root->right,r-l); NODE *t=root->right->left; t->add+=a,t->key+=a,t->minv+=a; splay(root,t); } void reverse(int l,int r){ select(root,l); select(root->right,r-l); NODE *t=root->right->left; t->rev=!t->rev; splay(root,t); } void revolve(int l,int r,int a){ select(root,l); select(root->right,r-l); select(root->right->left,root->right->left->size-a); select(root->right->left->right,root->right->left->right->size); NODE *p=root->right->left,*t=root->right->left->right; p->right=NIL; p->father->left=t,t->father=p->father; t->right=p,p->father=t; update(t);update(p); splay(root,p); } int query(int l,int r){ select(root,l); select(root->right,r-l); return root->right->left->minv; } }tree; int main(){ tree.init(); scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&x); tree.insert(x,i); } scanf("%d",&m);getchar(); while(m--){ scanf("%s",s); switch(s[0]){ case 'A': scanf("%d%d%d",&l,&r,&x); tree.plus(l,r+2,x); break; case 'I': scanf("%d%d",&pos,&x); tree.insert(x,pos+1); break; case 'D': scanf("%d",&pos); tree.remove(pos+1); break; case 'M': scanf("%d%d",&l,&r); printf("%d\n",tree.query(l,r+2)); break; case 'R': if(s[3]=='E'){ scanf("%d%d",&l,&r); tree.reverse(l,r+2); }else{ scanf("%d%d%d",&l,&r,&x); if(x%(r-l+1)) tree.revolve(l,r+2,x%(r-l+1)); } break; } getchar(); } return 0; }
相关文章推荐
- BZOJ 1895 & POJ 3580 supermemo (splay)
- POJ 3580(SuperMemo-Splay区间加)[template:Splay V2]
- POJ - 3580 SuperMemo (伸展树模板 全)
- [POJ 3580] SuperMemo
- Splay伸展树学习小记 Poj 3580 SuperMemo
- POJ 3580 SuperMemo(Splay模板)
- [poj][3580][SuperMemo]
- poj 3580 SuperMemo
- POJ 3580 SuperMemo(Splay树+内存池)
- POJ 3580 SuperMemo(Splay树)
- 【POJ】3580 SuperMemo
- poj 3580 SuperMemo(Treap平衡树解法)
- POJ 3580 SuperMemo
- 【POJ】3580 SuperMemo 【splay】
- POJ 3580 OpenJ_Bailian 4090 SuperMemo (伸展树模版)
- POJ 3580 SuperMemo [Splay]
- POJ-3580-SuperMemo(splay的各种操作)
- poj3580 SuperMemo
- POJ 题目3580 SuperMemo(Splay Tree区间加,区间翻转,区间右移,插入删除,区间最小值)
- poj-3580 SuperMemo[splay tree]