UVa 11922 Permutation Transformer(splay)
2015-06-02 21:17
363 查看
题目链接
题意:根据m条指令改变排列{1,2,3......n}。每条指令(a,b)表示取出第a~b个元素,翻转后天添加到排列的尾部。
题解:可以分解出三个操作,删除一个区间,添加一个区间,翻转一个区间。spaly的基本应用。
代码如下:
题意:根据m条指令改变排列{1,2,3......n}。每条指令(a,b)表示取出第a~b个元素,翻转后天添加到排列的尾部。
题解:可以分解出三个操作,删除一个区间,添加一个区间,翻转一个区间。spaly的基本应用。
代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<math.h> #include<queue> #include<stack> #include<set> #include<map> #include<vector> #include<string.h> #include<string> #include<stdlib.h> typedef long long LL; typedef unsigned long long LLU; const int nn=20; const int inf=0x3fffffff; const LL inf64=(LL)inf*inf; using namespace std; int n,m; struct node { int val; int cnt; bool fz; node* pre; node* ch[2]; }*root; void push_up(node *o) { if(o==NULL) return ; o->cnt=1; if(o->ch[0]!=NULL) o->cnt+=o->ch[0]->cnt; if(o->ch[1]!=NULL) o->cnt+=o->ch[1]->cnt; } void build(node* &o,node* fa,int l,int r) { int mid=(l+r)/2; o=new node; o->pre=fa; o->val=mid; o->cnt=(r-l+1); o->ch[0]=o->ch[1]=NULL; o->fz=false; if(l==r) return ; if(l<=mid-1) build(o->ch[0],o,l,mid-1); if(mid+1<=r) build(o->ch[1],o,mid+1,r); push_up(o); } void push_down(node* o) { if(o->fz) { o->fz=false; if(o->ch[0]!=NULL) { o->ch[0]->fz=!o->ch[0]->fz; swap(o->ch[0]->ch[0],o->ch[0]->ch[1]); } if(o->ch[1]!=NULL) { o->ch[1]->fz=!o->ch[1]->fz; swap(o->ch[1]->ch[0],o->ch[1]->ch[1]); } } } void Rotate(node *o) { node* x=o->pre; push_down(x); push_down(o); int d; if(x->ch[0]==o) d=0; else d=1; x->ch[d]=o->ch[d^1]; if(o->ch[d^1]!=NULL) { o->ch[d^1]->pre=x; } if(x->pre!=NULL) { if(x->pre->ch[0]==x) x->pre->ch[0]=o; else x->pre->ch[1]=o; } o->pre=x->pre; o->ch[d^1]=x; x->pre=o; push_up(x); // push_up(o); } void splay(node* o,node* f) { node* x; node* y; while(o->pre!=f) { if(o->pre->pre==f) Rotate(o); else { x=o->pre; y=x->pre; int d1,d2; if(y->ch[0]==x) d1=0; else d1=1; if(x->ch[0]==o) d2=0; else d2=1; if(d1==d2) { Rotate(x); Rotate(o); } else { Rotate(o); Rotate(o); } } } push_up(o); if(f==NULL) root=o; } void select(int k,node* f) { node* o=root; int tem; while(1) { tem=0; push_down(o); if(o->ch[0]!=NULL) { tem+=o->ch[0]->cnt; } if(tem>=k) o=o->ch[0]; else if(tem+1==k) break; else { o=o->ch[1]; k-=tem+1; } } splay(o,f); } void init() { root=NULL; root=new node; root->val=0; root->cnt=2; root->fz=false; root->pre=NULL; root->ch[0]=root->ch[1]=NULL; root->ch[1]=new node; root->ch[1]->val=0; root->ch[1]->cnt=1; root->ch[1]->fz=false; root->ch[1]->pre=root; root->ch[1]->ch[0]=root->ch[1]->ch[1]=NULL; } void display(node* o) { if(o==NULL) return ; push_down(o); display(o->ch[0]); if(o->val) printf("%d\n",o->val); display(o->ch[1]); } void solve(int l,int r) { select(l,NULL); select(r+2,root); node* o=root->ch[1]->ch[0]; root->ch[1]->ch[0]=NULL; splay(root->ch[1],NULL); o->fz=!o->fz; swap(o->ch[0],o->ch[1]); select(n-r+l,NULL); select(n-r+l+1,root); root->ch[1]->ch[0]=o; o->pre=root->ch[1]; splay(root->ch[1]->ch[0],NULL); } int main() { int a,b; scanf("%d%d",&n,&m); init(); build(root->ch[1]->ch[0],root->ch[1],1,n); splay(root->ch[1]->ch[0],NULL); while(m--) { scanf("%d%d",&a,&b); solve(a,b); } display(root); return 0; }
相关文章推荐
- LeetCode 56:Merge Intervals
- 开源收藏
- JAVA bootstrap ClassLoader和JAVA核心API替换
- 2015年第十三周oj:小球自由下落
- DTD基本语法
- nginx常见内部参数,错误总结
- 策略模式
- 1163
- Creating a Qt Quick Application(译)
- Django学习之用户登录
- [leetcode] Contains Duplicate III
- 大数据引发的联想--人工智能
- IOS判断当前日期在两个日期之间。
- jquery对标签属性操作
- python基础教程学习笔记---(7)python操作mysql
- java.io.Serializable浅析
- 使用erwin
- leetcode刷题 ,总结,记录,备忘。144
- 给textarea添加背景图
- Android+Sqlite 实现古诗阅读应用(三)