第一のチャネルAの厳密な意味での組み合わせは、特に最初のサーブ記念して、トピックをオフにカウントされます。
この種の問題への最初の本当の暴露、人々は非常に発散の仕事を考えているかのように感じる......
置換のための\(P_1、P_2、\ DOTS、P_N \) 、毎\(I \)に\(P_I \)片側に接続され、複数のリングを構成する図で発見することができ、目標は、ですこれらのリングは、自己リングになります。
補題:長さ\(N- \)シクロアルキルなる(N- \)\として最小スイッチング周波数からリング\(1-N- \。) 。
誘導証明書によって、現在の状況のために、任意の一時点での補題知らノックアウト法律によって設定二つのリングで彼らの分割を交換します。
注\(F_n \)は、スイッチング周波数を表し、少なくとも長さ\(N- \)シクロアルキルなる\(N- \)自己ループ、どのように多くの交換。以上のことから、我々は、2個の環がセット長に望むことができる、二つのリングにそれぞれを分割しなければならない(X、Y \)\、ノート\(T(x、y)は \) の異なる方法の数を表します。長さ\(N- \)ループ長となる(X、Y \)\ 2つのリングの、\(N- \)もあり、\(X = Y \)場合が\(T( X、Y)= \ FRAC {N-2}} {\) 、さもなければ\(T(X、Y)= N- \) 。ため(X \)\環(Y \)\リング干渉の動作、操作の両側がランダムに配置されてもよく、従って、これは複数のセットの完全な配列です。
そう再帰式を有する:\ [F_n = \ sum_ {} N-X + Y = \左(T(X、Y)F_xF_y \ FRAC {(2-N-)!} {(X-1)(Y-。! !1)} \右)\ ] のタイトルのためのすべての\(K \)リング、その長さを覚えて、\(\ {L_K \} \) 、最終的な答えは次のとおりです。\ [\のProd ^ {K} _ F_ {L_ {I 1 =} {iは}} \ dfrac {(NK)!} {\ PROD ^ {K} _ {i = 1から}(L_iを-1)!} \] 、終了していません洗礼の後JOJO見つかりました\(^ {} \ F_n = N-2-N-) !すぐに減少し、複雑(\ O(のn \ \)N-ログ) ......
(サンは、このループ動作は問題領域dalaoのみORZに対する解決策として学習されて見つけます
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
const ll mod=1e9+9;
int n,a[N],L[N],cnt;
ll fac[N]={1,1},F[N]={0,1};
bool vis[N];
ll qpow(ll bas,ll p)
{
ll res=1; bas%=mod;
for(;p;p>>=1)
{
if(p&1) res=res*bas%mod;
bas=bas*bas%mod;
}
return res;
}
int dfs(int x)
{
vis[x]=1;
if(vis[a[x]]) return 1;
return dfs(a[x])+1;
}
int main()
{
int T; scanf("%d",&T);
for(int i=2;i<N;++i)
fac[i]=i*fac[i-1]%mod,
F[i]=qpow(i,i-2)%mod;
while(T--)
{
memset(vis,0,sizeof(vis));
cnt=0;
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1;i<=n;++i)
if(!vis[i]) L[++cnt]=dfs(i);
ll ans=fac[n-cnt];
for(int i=1;i<=cnt;++i)
ans=ans*F[L[i]]%mod*qpow(fac[L[i]-1],mod-2)%mod;
printf("%lld\n",ans);
}
return 0;
}