https://codeforces.com/problemset/problem/1223/D
卧槽这题巨水,然而比赛的时候想到把离散化后把区间统计出来了,然而最后统计方式弄错了我透
其实就是要找到最长的连续数字段[l,r],他们数字在原序列中的相对位置是对的,然后其他数字依次挪到最左边和最右边。
如果一段数字[l,a-1][a+1,r]中间a数字的区间跟两边重合了或者不对,那么要挪动a,必须全部挪动[l,a-1]或者全部挪动[a+1,r],才能保证最后相对位置正确。
#include<bits/stdc++.h>
#define maxl 300010
using namespace std;
int n,m,tot,ans;
int a[maxl],num[maxl];
int al[maxl],ar[maxl];
char s[maxl];
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
num[i]=a[i];
}
sort(num+1,num+1+n);
tot=unique(num+1,num+1+n)-num-1;
for(int i=1;i<=n;i++)
{
a[i]=lower_bound(num+1,num+1+tot,a[i])-num;
al[i]=maxl,ar[i]=0;
}
for(int i=1;i<=n;i++)
{
al[a[i]]=min(i,al[a[i]]);
ar[a[i]]=max(i,ar[a[i]]);
}
}
inline void mainwork()
{
ans=tot-1;
int mx=0,cnt=1;
for(int i=2;i<=tot;i++)
{
if(ar[i-1]<al[i])
cnt++;
else
mx=max(cnt,mx),cnt=1;
}
mx=max(cnt,mx);ans=tot-mx;
}
inline void print()
{
printf("%d\n",ans);
}
int main()
{
int t=1;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}