CF1768D Lucky Permutation

 

/*
题意: 将序列 交换排序成 逆序对 为 1 的排序 
1.pre:置换环 pi -> a[pi] 最后会连成一个首尾相接的 环  答案是 n-cur 
2.若 pi+1 / pi-1 已经在了 逆序对 ==1 ->flag 
flag==0 Ans=n-cur+1
flag==1 Ans=n-cur-1
*/
/*
4
2
2 1
2
1 2
4
3 4 1 2
4
2 4 3 1

0 1 3 1
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string.h>
//#include<queue>
//#include<vector>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=2e5+10;
const int mod=998244353;
const int inf=0x3f3f3f3f;

int a[maxn],vis[maxn],n,cur,flag,num;

map< int,int > ring;

void dfs(int pos){
    if(vis[a[pos]]) return;
    vis[a[pos]]=1;
    ring[a[pos]]=1;
    if(ring[a[pos]-1]||ring[a[pos]+1]) flag=1;//????
    dfs(a[pos]);
}
int main()
{
    ios::sync_with_stdio(false);
    int T;cin>>T; //cout<<T<<endl;
    while(T--)
    {
        memset(vis,0,sizeof(vis));
        //memset(ring,0,sizeof(ring)); 
        cur=0; flag=0;
        
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=n;i++){
            if(vis[a[i]]==0){
                ++cur;    num=0;
            //    memset(ring,0,sizeof(ring)); 
                ring.clear();
                dfs(i);
            }
        }
        //cout<<cur<<endl;
        if(flag==0) cout<<n-cur+1<<'\n';
        else cout<<n-cur-1<<'\n';
        
    }

    return 0;
}

 

posted @ 2023-10-22 08:59  JMXZ  阅读(7)  评论(0)    收藏  举报