16 Educational Codeforces Round 142 (Rated for Div. 2)C. Min Max Sort(递归、思维、dp)
C. Min Max Sort
很不错的一道题目,不过脑电波和出题人每对上,\(qwq。\)
正难则反。
我们考虑最后一步是怎么操作的。
最后一步一定是对\(1\)和\(n\)进行操作
那么上一步呢?
上一步应该是对\(2\)和\(n-1\)
以此类推
第一步应该是对\(\frac{n}{2}\)和\(\frac{n}{2}+1\)
我们的答案应该是上一步之前的所有操作次数加上最后一步的操作次数。
然后对于\(i \in [1, \frac{n}{2}]\)并不是所有\(i\)都需要进行操作的。
如果本身\(i\)到\(n-i+1\)已经是有序的就不需要进行操作了。
如何判断是不是有序的呢?
这里预处理出来一个\(f_i\)表示,以\(i\)结尾的最长连续上升序列的长度。
如果\(f[n-i+1]<n-i+1-i+1\)说明这个\(i\)到\(n-i+1\)不是有序的则需要进行一次操作
#include <bits/stdc++.h>
#define int long long
#define rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define fep(i, a, b) for(int i = (a); i >= (b); --i)
#define _for(i, a, b) for(int i=(a); i<(b); ++i)
#define pii pair<int, int>
#define pdd pair<double,double>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define vi vector<int>
using namespace std;
const int maxn = 2e5 + 10;
int n,a[maxn],f[maxn];
void solve() {
cin>>n;
int lst=0;
rep(i,1,n){
f[i]=0;
cin>>a[i];
}
rep(i,1,n) {
f[a[i]]=f[a[i]-1]+1;
}
int ans=0;
fep(i,n/2,1){
if(f[n-i+1]<n-i+1-i+1){
ans++;
}
}
cout<<ans<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
// freopen("C:\\Users\\24283\\CLionProjects\\untitled2\\1.in", "r", stdin);
int _;
cin >> _;
while (_--)
solve();
return 0;
}