序号:5942
「EZEC-10」排列排序
Time Limit:1s Memory Limit:128MB
题目描述
小E给你一个长度为n的排列p1,p2,⋯,pn。小E想要把它排序。
小E每次可以花区间长度,即r−l+1的代价,选择排列中的任意一段区间[l,r],并将[l,r]从小到大排序。
现在你可以让他进行若干次这个操作,直到 pp 中元素的值从 11 到 nn 按升序排序,即对于1到n的每一个i,都有pi=i。
小E问你,他花的代价最少为多少?
输入格式
本题有多组询问,第一行有一个数T表示询问组数。
对于每组询问:
第一行给出一个整数n。
第二行n个整数,由空格隔开,代表排列p中元素的值。
输出格式
T行,每行一个整数表示一组询问的答案。
输入输出样例
输入 #1
2
3
1 3 2
4
3 2 1 4
输出 #1
2
3
说明/提示
【样例 11 说明】
对于第一组数据,可选择区间[2,3]进行排序。
对于第二组数据,可选择区间[1,3]进行排序。
【数据规模与约定】
对于20%的数据,n≤4。
对于另30%的数据,∑n≤5000。
对于另10%的数据,p1=n。
对于100%的数据,1≤T,∑n≤106。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,m,tot;
int p[N];
int val[N];
int a[N];
int main(){
ios::sync_with_stdio(false);
int _;
cin>>_;
while(_--){
cin>>n;
for(int i=1;i<=n;i++){
p[i]=a[i]=0;
}
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
if(i==a[i]){
continue;
}
int l=i,r=a[i];
if(l>r){
swap(l,r);
}
p[l]++,p[r+1]--;
}
for(int i=1;i<=n;i++){
p[i]+=p[i-1];
}
int ans=0;
for(int i=1;i<=n;i++){
if(p[i]){
ans++;
}
}
cout<<ans<<"\n";
}
return 0;
}