題意:給定一序列,每次可以選擇一個數,並將序列內所有數放在序列最前面/最後面,問使序列有序的最小操作數
考慮最差情況肯定是不同數字個數 - 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] << '\n';
// }
// cout << '\n';
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 << '\n';
}
return 0;
}
/*
2
00001000
0001000
000000000000000000000000000100000
000000000000000000000000000000000100000000000000000000000000000000000001001000000000000000000000000
00000000000000000000000000000000010000000000000000000000000000000000000100100
*/