Description

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

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

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

Input

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

Output

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

\(\\\)

根据Burnside引理,答案就是所有置换下不动元的平均数(人话)。一个置换可以理解为一种排列,所以置换总数就是\(n!\)。

然后考虑求出所有的不动元。

首先,假设我们已近得到了\(m\)个循环节,他们的长度分别为\(L_1,L_2...L_m\)\((L_1+L_2+...+L_m=n)\)。

然后连边的时候我们分两种情况:

  1. 边的两端在同一循环节内。
  2. 边的两端不在同一循环节内。
情况1:

我们设有循环节的大小为\(n\)。则有\(2^{\lfloor \frac{n}{2}\rfloor}\)种。

这个可以画图感受一下:我们先把点按\(1\)到\(n\)重标号,假设有边\((1,k)\),那么一定有边\((2,2+k-1),(3,3+k-1)...(n,k-1)\)(因为)。然后\(k>2^{\lfloor \frac{n}{2}\rfloor}\)情况一定与\(k-2^{\lfloor \frac{n}{2}\rfloor}\)等价。所以等价类有\(\lfloor \frac{n}{2}\rfloor\)个。

情况2:

我们设两个循环节大小分别为\(n,m\)。则有\(2^{gcd(n,m)}\)种。

我们又来感受一下:我们假设存在边\((1,i)\),则必有边\((2,i+1),(3,i+2)...\)如果想让这个循环回到\((1,i)\),那么至少要有\(lcm(n,m)\)条边,所以等价类有\(\frac{nm}{lcm(n,m)}=gcd(n,m)\)种。

然后我们得到了循环节为\((L_1,L_2...L_m)\)的图的情况数,我们还需要得到循环节为\((L_1,L_2...L_m)\)的\(n\)阶置换有多少种。

种数是\(\frac{n!}{\Pi B_i \Pi Li}\)(其中\(B_i\)表示长度为\(i\)的循环节数量)。

首先我们不妨设\((L_1\leq L_2\leq...\leq L_m)\)。然后我们按照\(1\)到\(m\)的顺序将得到的一个\(1\)到\(n\)的排列划分。这样就有\(n!\)个序列。

长度相同的循环节的排列会算重:比如\((1,2)(3,4)\)与\((3,4)(1,2)\)应该算作一种(这里\((1,2)\)仅仅表示\(1,2\)在一个循环中)。所以要除以\(\Pi B_i\)。

同一循环内也会算重:比如\((1,2,3)\)与\((2,3,1)\)算作一种(这里的\((1,2,3)\)表示的是\((\begin{matrix} 1 2 3\\ 2 3 1\end{matrix})\))。所以要除以\(\Pi Li\)。

然后就完了。

代码:

#include<bits/stdc++.h>
#define ll int
#define mod 997
#define N 65 using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;} int n;
int ksm(int t,int x) {
ll ans=1;
for(;x;x>>=1,t=t*t%mod)
if(x&1) ans=ans*t%mod;
return ans;
}
int gcd(int a,int b) {return !b?a:gcd(b,a%b);}
int g[N][N]; int f[N],fac[N],inv[mod+5];
int ans;
int num[N];
int cnt;
int pw2[100005];
void dfs(int v,int res) {
if(!res) {
int now=fac[n];
int mi=0;
for(int i=v+1;i<=n;i++) {
now=now*inv[fac[num[i]]*ksm(i,num[i])%mod]%mod;
mi+=i/2*num[i];
for(int j=i+1;j<=n;j++) {
mi+=g[i][j]*num[i]*num[j];
}
mi+=i*num[i]*(num[i]-1)/2;
}
now=now*pw2[mi%(mod-1)]%mod;
(ans+=now)%=mod; return ;
}
if(!v) return ;
num[v]=0;
dfs(v-1,res);
for(int i=1;i*v<=res;i++) {
num[v]=i;
dfs(v-1,res-i*v);
num[v]=0;
}
} int main() {
n=Get();
fac[0]=1;
for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
pw2[0]=1;
for(int i=1;i<=100000;i++) pw2[i]=(pw2[i-1]<<1)%mod; inv[0]=inv[1]=1;
for(int i=2;i<=mod;i++) inv[i]=inv[mod%i]*(mod-mod/i)%mod;
for(int i=1;i<=n;i++) {
for(int j=i;j<=n;j++) {
g[i][j]=gcd(i,j);
}
} dfs(n,n);
cout<<ans*ksm(fac[n],mod-2)%mod;
return 0;
}

Luogu P4727-- 【HNOI2009】图的同构记数的更多相关文章

  1. P4727 [HNOI2009]图的同构记数

    传送门 如果我们把选出子图看成选出边,进而看成对边黑白染色,那么就是上一题的弱化版了,直接复制过来然后令\(m=2\)即可 不过直接交上去会T,于是加了几发大力优化 不知为何华丽的被小号抢了rank2 ...

  2. BZOJ 1488 Luogu P4727 [HNOI2009]图的同构 (Burnside引理、组合计数)

    题目链接 (Luogu) https://www.luogu.org/problem/P4727 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.ph ...

  3. [HNOI2009]图的同构记数

    题意 在所以置换下,本质不同的\(n\)阶图个数 做法 可以假想成\(K_n\),边有黑白两色,黑边存在于原图,白边存在于补图 由于\(n\le 60\),可以手算出拆分数不大,所以我们爆搜置换群 对 ...

  4. 【BZOJ1488】[HNOI2009]图的同构(Burside引理,Polya定理)

    [BZOJ1488][HNOI2009]图的同构(Burside引理,Polya定理) 题面 BZOJ 洛谷 题解 求本质不同的方案数,很明显就是群论这套理论了. 置换一共有\(n!\)个,考虑如何对 ...

  5. bzoj1488 [HNOI2009]图的同构 Burnside 引理

    题目传送门 bzoj1488 - [HNOI2009]图的同构 bzoj1815 - [Shoi2006]color 有色图(双倍经验) 题解 暴力 由于在做题之前已经被告知是 Burnside 引理 ...

  6. bzoj1488[HNOI2009]图的同构

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1488 1488: [HNOI2009]图的同构 Time Limit: 10 Sec  M ...

  7. 记数排序 & 桶排序 & 基数排序

    为什么要写这样滴一篇博客捏...因为一个新初一问了一道水题,结果就莫名其妙引起了战斗. 然后突然发现之前理解的桶排序并不是真正的桶排序,所以写一篇来区别下这三个十分相似的排序辣. 老年菜兔的觉醒!!! ...

  8. Python02 标准输入输出、数据类型、变量、随记数的生成、turtle模块详解

    1 标准输出 python3利用 print() 来实现标准输出 def print(self, *args, sep=' ', end='\n', file=None): # known speci ...

  9. 记数问题(0)<P2013_1>

    记数问题 (count.cpp/c/pas) [问题描述]  试计算在区间1到n的所有整数中,数字x(0≤x≤9)共出现了多少次?例如,在1到11中,即在1.2.3.4.5.6.7.8.9.10.11 ...

随机推荐

  1. spring-boot-2.0.3之redis缓存实现,不是你想的那样哦!

    前言 开心一刻 小白问小明:“你前面有一个5米深的坑,里面没有水,如果你跳进去后该怎样出来了?”小明:“躺着出来呗,还能怎么出来?”小白:“为什么躺着出来?”小明:“5米深的坑,还没有水,跳下去不死就 ...

  2. python数据类型之内置方法

    python有六大数据类型,分别为整型.字符串.列表.字典.元祖和集合,这些基本数据类型都内置了很多方法,接下来一一探寻. python中整型有两种:int和float 1 int 使用dir函数查看 ...

  3. [转]VR原理讲解及开发入门

    本文转自:http://www.52vr.com/article-661-1.html 本文是作者obuil根据多年心得专门为想要入门的VR开发者所写,由52VR网站提供支持.   1. VR沉浸感和 ...

  4. T-SQL:基础练习(杂)

    1.返回 每月最后一天订单 SELECT orderid, orderdate, custid, empid FROM Sales.Orders WHERE orderdate = EOMONTH(o ...

  5. 【github&&git】7、gitignore 修改不起作用

    在git使用过程中有时会遇到修改了.gitignore文件,修改了之后发现,不能起作用,这是因为git存在缓存问题,所以做一下步骤即可: git rm -r --cached . git add . ...

  6. 《Head First设计模式》批注系列(一)——观察者设计模式

    最近在读<Head First设计模式>一书,此系列会引用源书内容,但文章内容会更加直接,以及加入一些自己的理解. 观察者模式(有时又被称为模型-视图(View)模式.源-收听者(List ...

  7. Mybatis事务管理

    一.Mybatis事务 1.事务管理方式 Mybatis中的事务管理方式有两种: 1.JDBC的事务管理机制,即使用JDBC事务管理机制进行事务管理 2.MANAGED的事务管理机制,Mybatis没 ...

  8. Js调试中不得不知的Console

    在js调试中,大部分的前端人员都是采用console.log()方法来打印出调试的数据,但是很多人都不知道console这个对象有很多很实在的方法,本文就来介绍一下这些方法的使用. 一.console ...

  9. layer插件layer.photos()动态插入的图片无法正常显示

    layer插件layer.photos()动态插入的图片无法正常显示,点击后面插入的图片,显示的是之前的图片列表,再次点击又是正常 有朋友遇到同样的问题 http://fly.layui.com/ji ...

  10. XHTML结构化

    XHTML 规则概要 将传统的 HTML 转换为 XHTML 1.0 是快捷且无痛的,只要你遵守一些简单的规则和容易的方针.不管是否使用过 HTML,都不会妨碍你使用 XHTML. 使用恰当的文档类型 ...