D. Lucky Permutation
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given a permutation†† pp of length nn.
In one operation, you can choose two indices 1≤i<j≤n1≤i<j≤n and swap pipi with pjpj.
Find the minimum number of operations needed to have exactly one inversion‡‡ in the permutation.
†† A permutation is an array consisting of nn distinct integers from 11 to nn in arbitrary order. For example, [2,3,1,5,4][2,3,1,5,4] is a permutation, but [1,2,2][1,2,2] is not a permutation (22 appears twice in the array), and [1,3,4][1,3,4] is also not a permutation (n=3n=3 but there is 44 in the array).
‡‡ The number of inversions of a permutation pp is the number of pairs of indices (i,j)(i,j) such that 1≤i<j≤n1≤i<j≤n and pi>pjpi>pj.
Input
The first line contains a single integer tt (1≤t≤1041≤t≤104) — the number of test cases. The description of test cases follows.
The first line of each test case contains a single integer nn (2≤n≤2⋅1052≤n≤2⋅105).
The second line of each test case contains nn integers p1,p2,…,pnp1,p2,…,pn (1≤pi≤n1≤pi≤n). It is guaranteed that pp is a permutation.
It is guaranteed that the sum of nn over all test cases does not exceed 2⋅1052⋅105.
Output
For each test case output a single integer — the minimum number of operations needed to have exactly one inversion in the permutation. It can be proven that an answer always exists.
Example
input
Copy
4
2
2 1
2
1 2
4
3 4 1 2
4
2 4 3 1
output
Copy
0 1 3 1
Note
In the first test case, the permutation already satisfies the condition.
In the second test case, you can perform the operation with (i,j)=(1,2)(i,j)=(1,2), after that the permutation will be [2,1][2,1] which has exactly one inversion.
In the third test case, it is not possible to satisfy the condition with less than 33 operations. However, if we perform 33 operations with (i,j)(i,j) being (1,3)(1,3),(2,4)(2,4), and (3,4)(3,4) in that order, the final permutation will be [1,2,4,3][1,2,4,3] which has exactly one inversion.
In the fourth test case, you can perform the operation with (i,j)=(2,4)(i,j)=(2,4), after that the permutation will be [2,1,3,4][2,1,3,4] which has exactly one inversion.
---------------------------------------------------------------------------------------------------------------------------------
图论建模题目,我们把下标与ai值相连,那么在一个联通块的数字就是需要互相交换的。先不考虑使得逆序对的个数为1,考虑怎么样变成0,显然是完全归位时的情况,也就是连通块大小-1的和。
那么再考虑逆序对为1,是什么情况呢,手写几个样例会发现,是两个相邻的交换位置
1 3 2 4 , 1 2 4 3 , 2 1 3 4其余位置不变。
那么就启示我们,我们最终归位之后,再交换一次相邻的就行了,然后我们会发现,过不了样例,原来是如果两个相邻的就在一个连通块的时候,我们是可以省去一次归位的次数的,这样就大功告成了。
# include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
vector<int>v[200000+10];
int book[200000+10];
int cnt,flag;
int nowsize;
void dfs(int now)
{
book[now]=cnt;
nowsize++;
if(book[now-1]==cnt||book[now+1]==cnt)
flag=1;
for(auto it:v[now])
{
if(book[it])
continue;
dfs(it);
}
}
int main ()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n+1;i++)
{
v[i].clear();
book[i]=0;
}
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
v[x].push_back(i);
v[i].push_back(x);
}
int ans=0;
flag=0;
for(int i=1;i<=n;i++)
{
if(book[i]==0)
{
cnt++;
nowsize=0;
dfs(i);
ans+=(nowsize-1);
}
}
// cout<<ans<< " **** "<<endl;
if(flag)
{
ans--;
}
else
{
ans++;
}
cout<<ans<<endl;
}
return 0;
}