[HNOI2009]图的同构

Description

求两两互不同构的含n个点的简单图有多少种。

简单图是关联一对顶点的无向边不多于一条的不含自环的图。

a图与b图被认为是同构的是指a图的顶点经过一定的重新标号以后,a图的顶点集和边集能完全与b图一一对应。

Input

输入一行一个整数N,表示图的顶点数,0<=N<=60

Output

输出一行一个整数表示含N个点的图在同构意义下互不同构的图的数目,答案对997取模。

Sample Input

输入1
1

输入2
2

输入3
3

Sample Output

输出1
1

输出2
2

输出3
4
群论入门中
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long lol;
 7 int Mod=997;
 8 lol n,A[1001],ans,fac[1001],cnt,num[10001],p[1001];
 9 int gcd(int a,int b)
10 {
11   if (b==0)
12     return a;
13   return gcd(b,a%b);
14 }
15 lol qpow(lol x,lol y)
16 {
17   lol res=1;
18   while (y)
19     {
20       if (y&1) res=(res*x)%Mod;
21       x=(x*x)%Mod;
22       y/=2;
23     }
24   return res;
25 }
26 void dfs(int now,int left)
27 {int i,j;
28   lol sum1=0,sum2=1;
29   if (left==0)
30     {
31       for (i=1;i<=cnt;i++)
32     {
33       sum1+=((num[i]-1)*num[i]/2)*p[i]+p[i]/2*num[i];
34       for (j=i+1;j<=cnt;j++)
35         sum1+=num[i]*num[j]*gcd(p[i],p[j]);
36       sum2=sum2*fac[num[i]]*qpow(p[i],num[i])%Mod;
37     }
38       sum2=fac[n]*A[sum2%Mod];
39       ans=(ans+sum2*qpow(2,sum1)%Mod)%Mod;
40       return;
41     }
42   if (now>left) return;
43     dfs(now+1,left);
44   for (i=1;i*now<=left;i++)
45     {
46       cnt++;
47       p[cnt]=now;
48       num[cnt]=i;
49       dfs(now+1,left-i*now);
50       cnt--;
51     }
52 }
53 int main()
54 {int i;
55   cin>>n;
56   A[1]=1;A[0]=1;
57   for (i=2;i<=996;i++)
58     A[i]=((Mod-Mod/i)*A[Mod%i])%Mod;
59   fac[0]=1;
60   for (i=1;i<=996;i++)
61     fac[i]=(fac[i-1]*i)%Mod;
62   dfs(1,n);
63   for (i=1;i<=n;i++)
64   ans=ans*A[i]%Mod;
65   cout<<ans;
66 }

 

posted @ 2017-12-28 20:31  Z-Y-Y-S  阅读(464)  评论(0编辑  收藏  举报