您的位置:首页 > 其它

UVa 11922 Permutation Transformer(splay)

2015-06-02 21:17 295 查看
题目链接

题意:根据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;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: