P10155 题解
I_will_AKIOI · · 题解
当我看到出题人题解时,发现我的做法原来这么麻烦,看来我还是太菜了。
首先,
其次,我们需要将
然后考虑暴力。从
由于在数组中无法高效的完成插入操作,我们可以使用链表。每次操作时将
若你使用数组存链表,注意空间要开两倍,不然会爆。
#include<bits/stdc++.h>
using namespace std;
struct data{int val,l,r;}w[4000005];
int n,m,cnt,ans,a[2000005],in[4000005];
void insert_left(int x,int y)//在x的左边插入y
{
int now=in[x];
w[++cnt]=data{y,w[now].l,now};
w[w[now].l].r=cnt;
w[now].l=cnt;
in[y]=cnt;
return;
}
void insert_right(int x,int y)//在x的右边插入y
{
int now=in[x];
w[++cnt]=data{y,now,w[now].r};
w[w[now].r].l=cnt;
w[now].r=cnt;
in[y]=cnt;
return;
}
void erase(int x)//删除x
{
int now=in[x];
int le=w[now].l,ri=w[now].r;
w[le].r=ri;
w[ri].l=le;
in[x]=0;
return;
}
int main()
{
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
insert_right(a[i-1],a[i]);//将a[i]插在a[i-1]的右边
if(i==n&&a[i]!=n)//a[n]不是n,无解
{
cout<<-1;
return 0;
}
}
for(int i=n-1;i>=1;i--)
{
if(w[in[i]].r==in[i+1]) continue;//当前i的→边就是i+1,跳过
erase(i);
insert_left(i+1,i);
//删除当前的数,再插入
ans++;
}
cout<<ans;
return 0;
}