Lien
https://www.acwing.com/problem/content/description/214/
Le titre
Étant donné un arrangement 1 ~ n p1, p2, ..., pn, vous pouvez effectuer plusieurs opérations, sélectionner deux entiers x, y à chaque fois, échanger px, py.
Supposons que le changement de p1, p2, ..., pn en un arrangement à croissance monotone 1,2, ..., n nécessite au moins m échanges.
Découvrez combien de méthodes de fonctionnement peuvent atteindre l'objectif ci-dessus avec seulement m échanges.
Étant donné que le résultat peut être volumineux, vous devez uniquement afficher la valeur après le module de \ (10 ^ 9 + 9 \) .
Par exemple, organiser \ (2,3,1 \) nécessite au moins 2 échanges pour devenir \ (1,2,3 \) . Il existe trois modes de fonctionnement, à savoir:
Première méthode: échangez d'abord le nombre \ (2,3 \) pour devenir \ (3,2,1 \) , puis échangez le numéro \ (3,1 \) pour devenir \ (1,2,3 \) .
Méthode 2: échangez d'abord le nombre \ (2,1 \) pour devenir \ (1,3,2 \) , puis échangez le numéro \ (3,2 \) pour devenir \ (1,2,3 \) .
Méthode 3: échangez d'abord le numéro \ (3,1 \) pour devenir \ (2,1,3 \) , puis échangez le numéro \ (2,1 \) pour devenir \ (1,2,3 \) .
Format d'entrée La
première ligne contient l'entier T, indiquant qu'il existe T ensembles de cas de test.
Il y aura une ligne vierge avant chaque cas de test.
Chaque scénario de test contient deux lignes, la première ligne contient l'entier n.
La deuxième ligne contient n entiers, représentant la séquence \ (p_1, p_2, ..., p_n \) .
Format de sortie
Chaque scénario de test génère un résultat et chaque résultat occupe une ligne.
Plage de données
\ (1≤n≤10 ^ 5 \)
Échantillon d'entrée:
3
3
2 3 1
4
2 1 4 3
2
1 2
Exemple de sortie:
3
2
1
Des idées
L'idée est de connecter le nombre \ (a [j] = i \) à un bord non dirigé vers i, ce qui générera des anneaux \ (cnt \) , et enfin nous diviserons les anneaux \ (cnt \) en n Bague.
Lemme: tout d'abord un \ (K \) de division de simple anneau en points \ (K \) ième boucle nécessite \ (k-1 \) échange secondaire
Pour un anneau, nous pouvons choisir deux points à échanger en deux petits anneaux.
Soit \ (f [i] \) le nombre de solutions qui divisent l'anneau de longueur i en i auto-chaînes avec le nombre minimum d'échanges.
Soit \ (T (x, y) \) le nombre de solutions pour diviser un anneau de longueur: \ (x + y \) en deux anneaux de longueur x, y. En supposant qu'il existe des méthodes x + y, on peut constater que lorsque x = y, la moitié des méthodes sont symétriques. Ce \ (x = y \) lorsque \ (T (x, y) = x \) , ou \ (T (x, y)
= x + y \) fonctionnant anneau interférence x complémentaire et la bague y, nous x La disposition de l'étape x-1 dans l'anneau et de l'étape y-1 sur l'anneau y est une disposition complète d'un ensemble double.
Il y a des anneaux cnt, et la longueur de chaque anneau est \ (l [i] \). La réponse finale est:
Même après avoir analysé cette étape, la complexité est toujours \ (O (n ^ 2) \) .
En jouant la table (non, la solution, nous pouvons voir que f [i] = \ (i ^ {i-2} \) , grâce à la puissance rapide : La nouvelle complexité temporelle est \ (O (nlogn) \)
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100010,mod=1e9+9;
int a[N],n,st[N],l[N],d;
int fac[N],f[N];
int qmi(int a,int b){
int res=1;
while(b){
if(b&1) res=(LL)res*a%mod;
a=(LL)a*a%mod;
b>>=1;
}
return res;
}
void dfs(int u){
d++;
st[u]=1;
if(!st[a[u]]) dfs(a[u]);
}
void init(){
fac[0]=1;
f[1]=1;
fac[1]=1;
for(int i=2;i<N;++i){
f[i]=qmi(i,i-2);
fac[i]=(LL)fac[i-1]*i%mod;
}
}
int main(){
int T;
init();
scanf("%d",&T);
while(T--){
memset(st,0,sizeof st);
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}
int cnt=0;
for(int i=1;i<=n;++i){
if(!st[i]) {
d=0;
dfs(i);
l[++cnt]=d;
}
}
int ans=fac[n-cnt]%mod;
for(int i=1;i<=cnt;++i){
ans=(LL)ans*f[l[i]]%mod*(LL)qmi(fac[l[i]-1],mod-2)%mod;
}
cout<<ans<<endl;
}
return 0;
}