题意:给定一序列,每次可以选择一个数,并将序列内所有数放在序列最前面/最后面,问使序列有序的最小操作数
考虑最差情况肯定是不同数字个数 - 1(完全无序和区间交叉)
考虑交换次数不容易思考,可以反向考虑最多的不用交换就有序的数字,
思考发现,当两个数字x < y,数字区间无交叉且数值间没有第三个数字时,这两个数字不用动就有序,
那么将题目数字抽象为线段并离散,使得最大连续数值不交(小数区间在前 大数区间在后)
总减x即可
/*
Zeolim - An AC a day keeps the bug away
*/
//#pragma GCC optimize(2)
//#pragma GCC ("-W1,--stack=128000000")
#include <bits/stdc++.h>
using namespace std;
#define mp(x, y) make_pair(x, y)
#define fr(x, y, z) for(int x = y; x < z; ++x)
#define pb(x) push_back(x)
#define mem(x, y) memset(x, y, sizeof(x))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef std::pair <int, int> pii;
typedef std::vector <int> vi;
//typedef __int128 ill;
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MOD = 386910137;
const ull P = 13331;
const int MAXN = 1e6 + 100;
int arr[MAXN] = {0};
struct lsh
{
int v[MAXN], vl;
lsh() { vl = 0; }
void pb(int val) { v[vl++] = val; } //?????
void init() { sort(v, v + vl); vl = unique(v, v + vl) - v; } //?????,????
int find(int val) { return lower_bound(v, v + vl, val) - v;} //??????
int get(int pos) { return v[pos]; } //????????
};
int mx[MAXN][2];
int dp[MAXN] = {0};
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
//freopen("d:out.txt","w",stdout);
//freopen("d:in.txt","r",stdin);
int n;
cin >> n;
while(n--)
{
int len;
cin >> len;
lsh V;
for(int i = 0; i < len; ++i)
{
cin >> arr[i];
V.pb(arr[i]);
dp[i] = 1;
}
V.init();
for(int i = 0; i < V.vl; ++i)
{
mx[i][0] = 0x3f3f3f3f;
mx[i][1] = 0;
}
len = unique(arr, arr + len) - arr;
for(int i = 0; i < len; ++i)
{
arr[i] = V.find(arr[i]);
mx[arr[i]][0] = min(mx[arr[i]][0], i); //变为线段
mx[arr[i]][1] = max(mx[arr[i]][1], i);
}
// for(int i = 0; i < len; ++i)
// {
// cout << mx[arr[i]][0] << ' ' << mx[arr[i]][0] << '
';
// }
// cout << '
';
int cut = 1;
for(int i = 0; i < len; ++i)
{
if(arr[i] == 0) continue;
if(mx[arr[i] - 1][1] < mx[arr[i]][0]) //计算最大连续递增不交线段数
{
dp[arr[i]] = dp[arr[i] - 1] + 1;
cut = max(cut, dp[arr[i]]);
}
}
cout << V.vl - cut << '
';
}
return 0;
}
/*
2
00001000
0001000
000000000000000000000000000100000
000000000000000000000000000000000100000000000000000000000000000000000001001000000000000000000000000
00000000000000000000000000000000010000000000000000000000000000000000000100100
*/