//这里写代码片
#include<cstdio>
#include<iostream>
#include<iostream>
using namespace std;
const int N=300010;
const int INF=1e9;
int size[N],v[N],pre[N],ch[N][2];
bool rev[N];
int n,a[N],top=0,root;
int get(int bh)
{
return ch[pre[bh]][0]==bh? 0:1;
}
void update(int bh)
{
if (!bh) return;
size[bh]=1;
if (ch[bh][0]) size[bh]+=size[ch[bh][0]];
if (ch[bh][1]) size[bh]+=size[ch[bh][1]];
}
void push(int bh)
{
if (!bh) return;
if (rev[bh])
{
if (ch[bh][0]) rev[ch[bh][0]]^=1;
if (ch[bh][1]) rev[ch[bh][1]]^=1;
swap(ch[bh][0],ch[bh][1]);
rev[bh]^=1;
}
}
void rotate(int bh)
{
int fa=pre[bh];
int grand=pre[fa];
int wh=get(bh);
ch[fa][wh]=ch[bh][wh^1];
pre[ch[fa][wh]]=fa;
ch[bh][wh^1]=fa;
pre[fa]=bh;
pre[bh]=grand;
if (grand) ch[grand][ch[grand][0]==fa? 0:1]=bh;
update(fa);
update(bh);
}
void down(int bh)
{
if (pre[bh]) down(pre[bh]);
push(bh);
}
void splay(int bh,int mb)
{
down(bh);
for (int fa;(fa=pre[bh])!=mb;rotate(bh))
if (pre[fa]!=mb)
rotate(get(bh)==get(fa)? fa:bh);
if (!mb) root=bh;
}
int find(int x)
{
int now=root;
while (1)
{
push(now);
if (size[ch[now][0]]>=x) now=ch[now][0];
else
{
int tmp=(ch[now][0]? size[ch[now][0]]:0);
tmp++;
if (tmp>=x) return now;
x-=tmp;
now=ch[now][1];
}
}
}
int build(int l,int r,int fa)
{
if (l>r) return 0;
int now=++top;
int mid=(l+r)/2;
ch[now][0]=build(l,mid-1,now);
ch[now][1]=build(mid+1,r,now);
v[now]=a[mid]; pre[now]=fa; rev[now]=0;
update(now);
return now;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
if (a[1]==1)
{
printf("0\n");
return 0;
}
a[0]=-INF; a[n+1]=INF;
root=build(0,n+1,0);
for (int i=1;i<=100000;i++)
{
int xx=find(1); //0的位置
int pos=find(2); //1的位置
if (v[pos]==1)
{
printf("%d\n",i-1);
break;
}
int yy=find(v[pos]+2);
if (xx!=root) splay(xx,0);
splay(yy,xx);
int t=ch[ch[root][1]][0];
rev[t]^=1;
update(ch[root][1]); update(root);
}
return 0;
}
cv1743 反转卡片(splay)
最新推荐文章于 2023-03-11 16:47:10 发布