Topic Link (but if the data in question)
The meaning of problems
data range
solution
First, the problem looks strange, can work to about converted, if A is seen as a ring of forest trees (there is an edge between i and Ai), B seen heavy reference points for these programs, then C may be understood to reference (in fact, this edge corresponds to) that point after i after the reference point of the weight is connected to the reference weight.
Then seek a ring may become several different nature tree multiplicity numeral program tree ring where the group refers to a Ci tree formed
Then find the number of different nature forest trees numeral ring embodiment may first find different nature each tree scheme reference number, and then seek the ring. The method is to use the excess amount is subtracted the total number, the tree, the excess when the number is the number of tree isomorphism ring, then each node on the first ring into the hash value of the root node of the tree outward, and then obtains the smallest ring, said ring having the look there have been no, the record with the map, then also remove this ring isomorphic tree number scheme. Since then subject age, the need to write precision.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7,step=233;
inline int read(){
char c=getchar();int t=0,f=1;
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){t=(t<<3)+(t<<1)+(c^48);c=getchar();}
return t*f;
}
int n,c[35],tag[35];
struct big{
const int mod=1e9;
ll a[5];
inline big& operator =(int x){
a[0]=x;a[1]=a[2]=a[3]=a[4]=0;
return *this;
}
inline big& operator *=(int x){
for(int i=0;i<5;i++)a[i]*=x;
for(int i=0;i<4;i++)a[i+1]+=a[i]/mod,a[i]%=mod;
}
inline big& operator /=(int x){
ll now=0;
for(int i=4;i>=0;i--){
now=now*mod+a[i];
a[i]=now/x;
now%=x;
}
}
inline void out(){
int tag=0;
for(int i=5;i>=0;i--){
if(tag)printf("%09lld",a[i]);
else if(a[i]||i==0)printf("%lld",a[i]),tag=1;
}
}
}ans;
vector<int> e[35];
ll alfa[35];
void dfs(int u){
for(int i=0;i<e[u].size();i++){
dfs(e[u][i]);
e[u][i]=alfa[e[u][i]];
}
sort(e[u].begin(),e[u].end());
alfa[u]=1;
int cnt;
for(int i=0;i<e[u].size();i++){
if(i==0||e[u][i]!=e[u][i-1])cnt=0;
cnt++;
ans/=cnt;
alfa[u]=(alfa[u]*step+e[u][i])%mod;
}
}
map<basic_string<int>,int> mp;
int main(){
n=read();
for(int i=1;i<=n;i++)c[i]=read();
for(int i=1;i<=n;i++){
for(int j=1,tmp=c[i];j<=n;j++,tmp=c[tmp]){
if(tmp==i)tag[i]=1;
}
if(tag[i]==0)e[c[i]].push_back(i);
}
ans=1;
for(int i=1;i<=n;i++)ans*=i;
for(int i=1;i<=n;i++)if(tag[i])dfs(i);
for(int i=1;i<=n;i++){
if(!tag[i])continue;
basic_string<int> x;
vector<basic_string<int> > v;
for(int j=i;tag[j];tag[j]=0,j=c[j]){
x+=alfa[j];
}
for(int i=0;i<x.size();i++){
v.push_back(x);
x=x.substr(1)+x[0];
}
sort(v.begin(),v.end());
if(!mp.count(v[0]))mp[v[0]]=0;
mp[v[0]]++;
ans/=mp[v[0]];
int cnt=v.size();
cnt/=(unique(v.begin(),v.end())-v.begin());
ans/=cnt;
}
ans.out();
puts("");
return 0;
}