题目传送门

题目大意: 问有多少个不同构的 nnn 个点的图。

题解

A图的顶点经过一定的重新标号以后,A图的顶点集和边集要完全与B图一一对应。这是题目里告诉我们的同构的条件,这应该算半个提示了,我们可以认为,重新标号是一种置换,这种置换形如:
(12...n−1na1a2...an−1an)\left( \begin{matrix} 1 & 2 & ... & n-1 & n\\ a_1 & a_2 & ... & a_{n-1} & a_n \end{matrix} \right) (1a1​​2a2​​......​n−1an−1​​nan​​)

那么总的置换数量就是 ∣G∣=n!|G|=n!∣G∣=n!,然后用burnside定理来求,也就是要求出每种置换有多少个不动点。

先将一个置换表示成若干个循环的乘积,然后考虑连边,假如循环 AAA 内第 xxx 个元素和第 yyy 个元素之间连了边,因为要在置换后图保持不变,所以第 x+1x+1x+1 和第 y+1y+1y+1 个元素之间也要有连边,同理,距离为 ∣x−y∣|x-y|∣x−y∣ 的元素之间都需要连边。

可以发现,对于一个长度 ddd,要么全部连边,要么全都不连,而 ddd 的取值范围是 [1,⌊Li2⌋][1,\lfloor \frac {L_i} 2 \rfloor][1,⌊2Li​​⌋],其中 LAL_ALA​ 是这个循环的长度,则一共有 2⌊Li2⌋2^{\lfloor \frac {L_i} 2 \rfloor}2⌊2Li​​⌋ 种连边方案。

再考虑两个不同的循环 AAA 和 BBB,类似的,假如 AAA 中的第 iii 个元素和 BBB 中的第 jjj 个元素之间连了边,那么 i+1i+1i+1 和 j+1j+1j+1 之间也要连,以此类推下去要连 lcm(LA,LB)lcm(L_A,L_B)lcm(LA​,LB​) 条边,不妨称这样的 (i,j),(i+1,j+1)(i,j),(i+1,j+1)(i,j),(i+1,j+1) 为同一组边。

因为一共有 LA×LBL_A\times L_BLA​×LB​ 条边,所以一共有 LA×LBlcm(,LA),LB=gcd⁡(LA,LB)\frac {L_A\times L_B} {lcm(,L_A),L_B}=\gcd(L_A,L_B)lcm(,LA​),LB​LA​×LB​​=gcd(LA​,LB​) 组边,每组边也是要么连要么不连,方案数为 2gcd⁡(LA,LB)2^{\gcd(L_A,L_B)}2gcd(LA​,LB​)。

所以答案就是:
1∣G∣∑L1,L2,...,Lk(∏i=1k2⌊Li2⌋×∏1≤A<B≤k2gcd⁡(LA,LB))\frac 1 {|G|}\sum_{L_1,L_2,...,L_k}\left(\prod_{i=1}^k2^{\lfloor \frac {L_i} 2 \rfloor}\times \prod_{1\leq A<B\leq k} 2^{\gcd(L_A,L_B)}\right) ∣G∣1​L1​,L2​,...,Lk​∑​(i=1∏k​2⌊2Li​​⌋×1≤A<B≤k∏​2gcd(LA​,LB​))

但是这样的话时间复杂度为 O(n!×n2)O(n!\times n^2)O(n!×n2),可以愉快地得到 TLETLETLE 的好成绩。

考虑优化,观察后可以发现,我们并不关心每个循环内的点是谁,只关心这个置换能拆成几个循环以及每个循环的大小 LiL_iLi​。

于是考虑直接枚举 LiL_iLi​,相当于将 nnn 进行自然数拆分,经暴力发现,当 n=60n=60n=60 时,拆分方案大概只有 10610^6106 种,可以接受。

当我们枚举出所有 LiL_iLi​ 之后,就可以用上面的柿子求解,但是还需要求多一个东西:有多少个置换拆成循环之后,循环的长度分别是 L1,L2,...,LkL_1,L_2,...,L_kL1​,L2​,...,Lk​。

这个很简单,排列组合一下就能得到:

先给这 kkk 个循环安排元素进去,方案数为 n!∏i=1kLi!\dfrac {n!} {\prod_{i=1}^k L_i!}∏i=1k​Li​!n!​。

再考虑每个循环内的元素顺序,不考虑重复的话就有 Li!L_i!Li​! 排列,但是对于一个循环而言,(a1a2a3...an)(a_1a_2a_3...a_n)(a1​a2​a3​...an​) 和 (a2a3a4...ana1)(a_2a_3a_4...a_na_1)(a2​a3​a4​...an​a1​) 其实是同样的排列,所以要除以 LiL_iLi​,即方案数为 Li!Li=(Li−1)!\dfrac {L_i!} {L_i}=(L_i-1)!Li​Li​!​=(Li​−1)!。

然后对于长度相同的两个循环,比如说 (12)(34)(1~2)(3~4)(1 2)(3 4),它其实等价于 (34)(12)(3~4)(1~2)(3 4)(1 2),设长度为 iii 的循环有 SiS_iSi​ 个,那么还需要除以 ∏i=1kSi!\prod_{i=1}^k S_i!∏i=1k​Si​!。

所以一共有 n!∏i=1kLi×∏i=1kSi!\frac {n!} {\prod_{i=1}^k L_i\times\prod_{i=1}^k S_i!}∏i=1k​Li​×∏i=1k​Si​!n!​ 个置换满足要求。

枚举出 LLL 之后,把这个方案数和上面那个柿子乘起来就是答案了。以及,这里的 n!n!n! 和上面的 1∣G∣\frac 1 {|G|}∣G∣1​ 可以抵消掉。

设对 nnn 进行自然数拆分的时间复杂度为 KKK,那么最后的时间复杂度为 O(K×n2)O(K\times n^2)O(K×n2)。

讲道理,当 n=60n=60n=60 的时候时间复杂度大概为 3.6×1093.6\times 10^93.6×109,虽然说完全跑不满,但是实测也需要 3s3s3s 左右,为什么能过呢……

太烧脑了果然还是不管好了qwq,代码如下:

#include <cstdio>
#define mod 997
#define maxn 110int n;
int ksm(int x,int y)
{int re=1;while(y){if(y&1)re=1ll*re*x%mod;x=1ll*x*x%mod;y>>=1;}return re;
}
int fac[maxn],inv_fac[maxn],inv[maxn],gcd[maxn][maxn];
int gcd_(int x,int y){return y==0?x:gcd_(y,x%y);}
void work()
{fac[0]=inv_fac[0]=inv[1]=1;for(int i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%mod;inv_fac[n]=ksm(fac[n],mod-2);for(int i=n-1;i>=1;i--)inv_fac[i]=1ll*inv_fac[i+1]*(i+1)%mod;for(int i=2;i<=n;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)gcd[i][j]=gcd_(i,j);
}
int L[maxn],S[maxn],ans=0;
void work(int k)
{int prod=1;for(int i=1;i<=k;i++)prod=1ll*prod*((1ll<<(L[i]/2))%mod)%mod;for(int i=1;i<=k;i++)for(int j=i+1;j<=k;j++)prod=1ll*prod*(1ll<<gcd[L[i]][L[j]])%mod;for(int i=1;i<=k;i++)prod=1ll*prod*inv[L[i]]%mod;for(int i=1;i<=n;i++)prod=1ll*prod*inv_fac[S[i]]%mod;ans=(ans+prod)%mod;
}
int min(int x,int y){return x<y?x:y;}
void dfs(int x,int k)
{if(!x)return (void)work(k-1);for(int i=min(L[k-1],x);i>=1;i--)L[k]=i,S[i]++,dfs(x-i,k+1),S[i]--;
}int main()
{scanf("%d",&n);work();L[0]=n;dfs(n,1);printf("%d",ans);
}

HNOI 2009 图的同构记数 题解相关推荐

  1. 解决CSV文件中长数字以科学记数格式保存问题

    今天因为需要做数据导入到数据表中,用xlxs文件做好了转化为csv文件,结果一看×××,傻眼了,全部变为科学记数了,在xlxs设置好的单元格格式为文本,可是转化为csv之后就变为了常规,而且×××也改 ...

  2. Vijos P1848 记数问题【进制】

    描述 试计算在区间 1 到 n 的所有整数中,数字 x(0 ≤ x ≤ 9)共出现了多少次?例如,在 1 到 11 中,即在 1.2.3.4.5.6.7.8.9.10.11 中,数字 1 出现了 4 ...

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

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

  4. C# LeetCode刷题 - Leetcode 306. 累加数 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  5. C#版 - Leetcode 306. 累加数 - 题解

    C#版 - Leetcode 306. 累加数 - 题解 306.Additive Number 在线提交: https://www.gaimor.cn 累加数是一个字符串,组成它的数字可以形成累加序 ...

  6. JzxxOJ Problem 4209: 寻找雷劈数 题解

    4209: 寻找雷劈数 题解 这是OJ的一道题,主要考验了数字的拆分,比较简单的! 题目 Code #include<iostream> #include<cstdio> #i ...

  7. NC65 对上年度反结账,调整数据后重新结账后,对本年度年初重算时系统报错:更新记数错误。

    1.对上年度反结账,调整数据后重新结账后,对本年度年初重算时系统报错:更新记数错误. 解决方案: 1.在期初余额节点,按Ctrl+ALT+A重建期初凭证: 2.到结账节点,重建余额表,选择有问题的财务 ...

  8. mysql更新后变成科学记数,CONVERT函数解决

    背景: 通过sql更新某个长数字字符串字段+1,结果变成了科学记数 例如: 初始数据如下,更新id+1 执行sql: UPDATE test set id = id + 1 结果如下: 原因:数据类型 ...

  9. python用turtle输入数字_Python02 标准输入输出、数据类型、变量、随记数的生成、turtle模块详解...

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

  10. 记数排序 桶排序 基数排序

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

最新文章

  1. linux分享一:网络设置
  2. 发布servlet版 Ajax 验证码验证组件
  3. 簡單SQL存儲過程實例
  4. julia有 pytorch包吗_用 PyTorch 实现基于字符的循环神经网络 | Linux 中国
  5. 全地球的水也没办法将这个“特殊”的瓶子装满!
  6. java中 private final_Java笔记:final与private关键字
  7. spring整合web
  8. 如何正确选择MySQL数据列类型
  9. 极限学习机ELM回归预测及其MATLAB代码实现
  10. C#调用TSC打印机打印数据
  11. 运筹系列31:内点法python代码
  12. 中标麒麟使用centos源_中标麒麟操作系统使用笔记
  13. PFC(Power Factor Correction)功率因数校正电路
  14. python总结之函数定义(一)
  15. 联想g400从u盘启动计算机,联想G40怎么从U盘启动|联想G40设置U盘启动方法
  16. 【xinfanqie】笔者支招:让Win7系统下的硬盘不在狂闪的诀窍
  17. php 计算月差,php计算月份差
  18. python读取excel的路径
  19. 如何用c语言添加背景图片,如何实现在单文档的窗口背景上贴上图片?
  20. 如何极速下载网页上的文件? 怎么批量下载文献

热门文章

  1. 一人饮酒醉用计算机版,玩家自制游戏版《一人饮酒醉》,歪唱喊麦笑翻全场
  2. 短视频运营小技巧,掌握推荐机制很重要,吸粉引流也不难
  3. Less颜色混合函数(14)
  4. 西门子定位器6DR5010-0NN00-0AA0
  5. 平面设计和3D建模哪个好找工作?
  6. Php计算圆柱的表面积和体积,圆柱体的面积计算公式
  7. API安全前景与趋势
  8. android 华为摄像头权限_Android踩坑日记(一):android7.0动态相机权限
  9. 最新Flutter 微信分享功能实现
  10. win10提升性能的服务器,win10专业版设置优化提高系统性能图解