[HNOI2009] 图的同构计数
因为要求本质不同的图,容易想到群论。
为了方便处理,将边是否存在转化为边的黑白染色问题(实际上就是 \([SHOI2006]\) 有色图 的弱化版本,最终公式也差不多)。
根据 \(Burnside\) 引理和 \(Polya\) 定理,将问题转化为:对于每种置换方案,有多少个边的等价类。
考虑对于一种置换方案 \(g\),设它有 \(k_g\) 个循环节,每个循环节长度为 \(a_{g,i}\)。
现在我们将问题分为两个部分:循环节内的等价类数量和循环节间的等价类数量。
对于循环节内部,容易想到将其转化为一个正 \(a_{g,i}\) 边形,其中长度相同的边在同一等价类中,所以循环节内部等价类数量就是 \(\sum\lfloor \dfrac{a_{g,i}}{2}\rfloor\)。
对于循环节间,为了让其对齐,所以要进行 \(\text{lcm}(a_{g,i},a_{g,j})\) 次轮换才能对齐一次,所以等价类个数为 \(\dfrac{a_{g,i}\times a_{g,j}}{\text{lcm}(a_{g,i},a_{g,j})}=\gcd(a_{g,i},a_{g,j})\)。
那么对于一个置换 \(g\),它的等价类总数就是 \(f'(g)=\sum\limits_{i=1}^{k_g}\lfloor\dfrac{a_{g,i}}{2}\rfloor+\sum\limits_{i=1}^{k_g-1}\sum\limits_{j=i+1}^{k_g}\gcd(a_{g,i},a_{g,j})\)。
根据 \(Burnside\) 引理,答案就是 \(\dfrac{1}{|G|}\sum\limits_{g\in G}2^{f'(g)}\)。
但是由于 \(|G|=n!\),所以仍然无法通过。考虑枚举 \(a_g\) 数组。
设 \(f(a)=\sum\limits_{i=1}^{k}\lfloor \dfrac{a_i}{2}\rfloor+\sum\limits_{i=1}^{k-1}\sum\limits_{j=i+1}^k\gcd(a_i,a_j)\),\(num(a)\) 表示循环节情况为 \(a\) 的置换的个数,则答案可以改写为 \(\dfrac{1}{|G|}\sum\limits_a2^{f(a)}num(a)\)。
这里 \(dfs\) 拆分 \(n\) 为多个数的和时间复杂度不会证,但是应该没有问题,以后再补这个锅吧。
那么问题来到了如何求解 \(num(a)\) 上。
首先将 \(n\) 个数分到 \(a_i\) 里,方案数为 \(\dfrac{n!}{\prod_{i=1}^ka_i!}\),乘上圆排列的方案数 \(\prod_{i=1}^k(a_i-1)!\),得方案数为 \(\dfrac{n!}{\prod_{i=1}^ka_i}\)。
但这样并不正确,因为相同长度的循环节可以互相交换,导致重复。因此设 \(b_i=\sum\limits_{j=1}^k[a_j=i]\),于是就可以得到最终形态:
\]
将 \(num(a)\) 带入原式得:
\]
\]
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=65,p=997;
int n,ans,a[N],b[N],jc[N],gc[N][N];
int gcd(int x,int y){
return !y?x:gcd(y,x%y);
}int qpow(int x,int y){
int re=1;
while(y){
if(y&1) re=re*x%p;
x=x*x%p,y>>=1;
}return re;
}void check(int k){
int f=0,prd=1;
for(int i=1;i<=k;i++){
f+=a[i]/2;
for(int j=i+1;j<=k;j++)
f+=gc[a[i]][a[j]];
}for(int i=1;i<=k;i++)
prd=prd*a[i]%p;
for(int i=1;i<=n;i++)
prd=prd*jc[b[i]]%p;
ans=(ans+qpow(2,f)*qpow(prd,p-2))%p;
}void dfs(int x,int num,int lst){
if(!num) return check(x-1),void();
for(int i=lst;i<=num;i++)
b[i]++,a[x]=i,dfs(x+1,num-i,i),b[i]--;
}signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n,jc[0]=1;
for(int i=1;i<=n;i++)
jc[i]=jc[i-1]*i%p;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
gc[i][j]=gcd(i,j);
dfs(1,n,1),cout<<ans;
return 0;
}
[HNOI2009] 图的同构计数的更多相关文章
- 【BZOJ1488】[HNOI2009]图的同构计数
题目链接 题意 求 n 个点的同构意义下不同的图的数量.\((n\leq 60)\) Sol \(Polya\) 定理的练手题. 我们这里先把边的存在与否变成对边进行黑白染色,白色代表不存在,这样就变 ...
- 【BZOJ1488】[HNOI2009]图的同构(Burside引理,Polya定理)
[BZOJ1488][HNOI2009]图的同构(Burside引理,Polya定理) 题面 BZOJ 洛谷 题解 求本质不同的方案数,很明显就是群论这套理论了. 置换一共有\(n!\)个,考虑如何对 ...
- bzoj1488[HNOI2009]图的同构
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1488 1488: [HNOI2009]图的同构 Time Limit: 10 Sec M ...
- bzoj1488 [HNOI2009]图的同构 Burnside 引理
题目传送门 bzoj1488 - [HNOI2009]图的同构 bzoj1815 - [Shoi2006]color 有色图(双倍经验) 题解 暴力 由于在做题之前已经被告知是 Burnside 引理 ...
- BZOJ 1488 Luogu P4727 [HNOI2009]图的同构 (Burnside引理、组合计数)
题目链接 (Luogu) https://www.luogu.org/problem/P4727 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.ph ...
- BZOJ 1488: [HNOI2009]图的同构 polay
题意:两个图AB同构:把A的顶点重新编号后与B一模一样.求n个顶点的图一共有多少个?(同构的算一种) 思路:边有n*(n-1)/2,这些边可以有可以没有,所以等同于边的颜色有两种.然后将n划分成循环节 ...
- BZOJ 1488: [HNOI2009]图的同构 [Polya]
完全图中选出不同构的简单图有多少个 上题简化版,只有两种颜色....直接copy就行了 太诡异了,刚才电脑上多了一个不动的鼠标指针,然后打开显卡管理界面就没了 #include<iostream ...
- [HNOI2009]图的同构
Description 求两两互不同构的含n个点的简单图有多少种. 简单图是关联一对顶点的无向边不多于一条的不含自环的图. a图与b图被认为是同构的是指a图的顶点经过一定的重新标号以后,a图的顶点集和 ...
- [bzoj1488][HNOI2009]图的同构——Polya定理
题目大意 求两两互不同构的含n个点的简单图有多少种. 简单图是关联一对顶点的无向边不多于一条的不含自环的图. a图与b图被认为是同构的是指a图的顶点经过一定的重新标号以后,a图的顶点集和边集能完全与b ...
- bzoj 1488: [HNOI2009]图的同构
Description 求两两互不同构的含n个点的简单图有多少种. 简单图是关联一对顶点的无向边不多于一条的不含自环的图. a图与b图被认为是同构的是指a图的顶点经过一定的重新标号以后,a图的顶点集和 ...
随机推荐
- 深入理解 HTTP 协议:从基础到实践全解析
在当今数字化时代,HTTP 协议如同互联网世界的"语言",支撑着无数网页浏览.数据传输和在线交互.无论你是初涉编程的新手,还是经验丰富的开发者,深入掌握 HTTP 协议都至关重要. ...
- 03C++顺序结构(2)
一.变量.赋值语句与表达式 1.天安门广场在北京市中心,它南北长880米,东西宽500米,试编一程序,计算天安门广场面积是多少平方米. 点击查看代码 1 //试编程,计算天安门广场的面积是多少平方米 ...
- ECShop开源商城与COS互通:降低本地存储负载、提升访问体验
ECShop简介 ECShop是一款开源电子商务平台,具有简单易用.安全稳定.模块化设计等特点.它提供了完整的电子商务解决方案,包括商品管理.订单管理.支付管理.配送管理.会员管理.促销管理.数据统计 ...
- 各种各样的 Host Builder
各种各样的 Host Buider If you're building for the web or writing a distributed application, you might nee ...
- 用Python让两组数据纵向排序
一.引言 在数据处理和分析中,排序是一项非常基础且重要的操作.排序可以帮助我们更好地理解数据,发现数据中的模式和规律.在Python中,我们可以使用多种方法对数据进行排序.本文将详细介绍如何使用Pyt ...
- Go语言实现国密证书加密与解析技术详解
Go语言实现国密证书加密与解析技术详解 前言 在当今数字化时代,信息安全成为企业和个人关注的焦点.国密算法作为中国自主研发的加密标准,广泛应用于各类安全场景.Go语言以其简洁.高效的特性,成为众多开发 ...
- Java代码打成jar后 classgetClassLoadergetResource("")返回为null
用maven打成jar包后,Main.class.getClassLoader().getResource("")为null. 示例: public static void mai ...
- TB交易开拓者_趋势跟踪策略_多品种对冲_递进优化回测_A0001188020期货量化策略
如果您需要代写技术指标公式, 请联系我. 龙哥QQ:591438821 龙哥微信:Long622889 也可以把您的通达信,文华技术指标改成TB交易开拓者的自动交易量化策略. 众所周知,投资界有基本面 ...
- [转]CMake与Make最简单直接的区别
写程序大体步骤为: 1.用编辑器编写源代码,如.c文件. 2.用编译器编译代码生成目标文件,如.o. 3.用链接器连接目标代码生成可执行文件,如.exe. 但如果源文件太多,一个一个编译时就会特别麻烦 ...
- [转]vue项目启动时,npm run serve 和 npm run dev 的区别
npm run serve 和 npm run dev 的区别 在我们运行一些 vue 项目的时候,输入npm run serve或者 npm run dev的其中一个时,系统会报错: PS C:\U ...