bzoj 2192 (request group essentially different ring forest tree scheme reference number)

Topic Link (but if the data in question)

The meaning of problems

(Too much trouble or directly on the map)

data range

n < = 30 n<=30

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;
}

Published 62 original articles · won praise 1 · views 996

Guess you like

Origin blog.csdn.net/wmhtxdy/article/details/103833131