题目链接

题意

求 n 个点的同构意义下不同的图的数量。\((n\leq 60)\)

Sol

\(Polya\) 定理的练手题。

我们这里先把边的存在与否变成对边进行黑白染色,白色代表不存在,这样就变成了一个对完全图中的边进行染色的问题,于是可以使用 对\(Burnside\)引理 进行优化后的 \(Polya\) 定理。

显然总的置换群大小是 \(n!\) 对应了每一种对边进行重新编号的方案,关键就在于要求出不动点的个数。

使用 \(Polya\) 定理,那么只需要求出所有关于边的置换中每一个置换被分成的循环总个数(也就是等价类总个数)。

显然每一个对于点的置换都唯一对应一个对于边的置换。但是即使是这样,置换数目依然是不可枚举的。所以我们肯定要另求他法。

由于最后的计算只和被分解成的循环个数有关,于是我们可以爆搜出所有的整数拆分方案代表最后循环的格式。

考虑可能处于一个等价类的边集要么这些边的端点都位于一个点的循环内部,要么这些边的端点仅连接了两个不同的循环。

首先考虑一个循环内部边集的等价类个数,假设有 n 个点,那么只用考虑这 n 个点的完全图中的边。我们把这些点排成一排,这样每一条边就有了一个跨度,循环一次相当于把这些点全部往前挪动一位并且把最前面的点扔到最后面去,这样显然跨度相同的边会在一个等价类里,然后由于这是一个环 那么跨度为 \(d\) 的和跨度为 \(n-d+1\) 的也是等价的 , 跨度总共有\((n-1)\)种于是总共有 \(\lfloor \frac{n}{2} \rfloor\) 种等价类。

然后考虑两个循环之间的等价类个数 , 假设大小为别为 \(a,b\) , 我们把两个循环就看作是一个环 , 每次置换相当于是把两个环同时转动一圈 , 这样子总共会便历到的边就有 \(lcm(a,b)\) 条 , 然后边总共有 \(a*b\) 条,于是就有 \(\frac{a*b}{lcm(a,b)}=gcd(a,b)\) 种等价类。

这样我们就算完一种类型的置换的贡献了,显然这样的置换是有许多个的,我们还要乘上一个系数,也就是满足我们整数拆分中枚举的格式的置换个数 , 考虑一个排列然后把重复的去掉即可,总数为:

\[\dfrac{n!}{\prod_{i=1}c_i!*i^{c_i}}
\]

\(c_i\)表示大小为 \(i\) 的循环个数

我们把一个排列直接认为是把循环按大小顺序排好的结果。

这样对于相同大小的循环,他们随便排列都是没有关系的,所以除掉 \(c_i!\) , 然后对于大小为 i 的一个循环来说 , 它的内部不断循环也是相同的方案 , 所以每一个大小为 \(i\) 的循环都要在方案中再除掉 \(i\)。

code:

#include<bits/stdc++.h>
#define Set(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=61;
const int mod=997;
template <typename T> inline void init(T&x){
x=0;char ch=getchar();bool t=0;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
if(t) x=-x;return;
}
typedef long long ll;
typedef unsigned long long ull;
template <typename T>inline void Inc(T&x,int y){x+=y;if(x>=mod) x-=mod;return;}
template <typename T>inline void Dec(T&x,int y){x-=y;if(x < 0) x+=mod;return;}
template <typename T>inline int fpow(int x,T k){int ret=1;for(;k;k>>=1,x=(ll)x*x%mod) if(k&1) ret=(ll)ret*x%mod;return ret;}
int Sum(int x,int y){x+=y;if(x>=mod) return x-mod;return x;}
int Dif(int x,int y){x-=y;if(x < 0 ) return x+mod;return x;}
int n;
int size[N],num[N],top=0,rest=0,cnt=0,mx=0;
int Gcd[N][N],bits[N],finv[N];
int ans=0;
inline int gcd(int a,int b){return b? gcd(b,a%b):a;}
inline void Calc(){
int nomove=0;int Inv=1;
for(int i=1;i<=top;++i) {
nomove+=num[i]*(size[i]>>1);
Inv=Inv*finv[num[i]]*fpow(fpow(size[i],num[i]),mod-2)%mod;
nomove+=num[i]*(num[i]-1)/2*size[i];
for(int j=i+1;j<=top;++j) {
int g=Gcd[size[i]][size[j]];
nomove+=g*num[i]*num[j];
}
}
Inc(ans,fpow(2,nomove)*Inv%mod);
return;
}
void Dfs(int pre){
int now=rest;if(!rest) {Calc();return;}
for(int i=pre+1;i<=now;++i) {
for(int j=1;j*i<=now;++j) {
rest=now-i*j;
size[++top]=i,num[top]=j;
Dfs(i);--top;
}
}
}
int main()
{
init(n);if(!n) return puts("1"),0;bits[0]=1,finv[1]=1,bits[1]=2;
for(int i=2;i<=n;++i) bits[i]=Sum(bits[i-1],bits[i-1]),finv[i]=(ll)(mod-mod/i)*finv[mod%i]%mod;
for(int i=2;i<=n;++i) finv[i]=(ll)finv[i-1]*finv[i]%mod;
for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) Gcd[i][j]=gcd(i,j);
rest=n;Dfs(0);cout<<ans<<endl;
return 0;
}

【BZOJ1488】[HNOI2009]图的同构计数的更多相关文章

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

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

  2. bzoj1488[HNOI2009]图的同构

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

  3. [bzoj1488][HNOI2009]图的同构——Polya定理

    题目大意 求两两互不同构的含n个点的简单图有多少种. 简单图是关联一对顶点的无向边不多于一条的不含自环的图. a图与b图被认为是同构的是指a图的顶点经过一定的重新标号以后,a图的顶点集和边集能完全与b ...

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

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

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

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

  6. [BZOJ1815&BZOJ1488]有色图/图的同构(Polya定理)

    由于有很多本质相同的重复置换,我们先枚举各种长度的点循环分别有多少个,这个暴搜的复杂度不大,n=53时也只有3e5左右.对于每种搜索方案可以轻易求出它所代表的置换具体有多少个. 但我们搜索的是点置换组 ...

  7. BZOJ 1488: [HNOI2009]图的同构 polay

    题意:两个图AB同构:把A的顶点重新编号后与B一模一样.求n个顶点的图一共有多少个?(同构的算一种) 思路:边有n*(n-1)/2,这些边可以有可以没有,所以等同于边的颜色有两种.然后将n划分成循环节 ...

  8. BZOJ 1488: [HNOI2009]图的同构 [Polya]

    完全图中选出不同构的简单图有多少个 上题简化版,只有两种颜色....直接copy就行了 太诡异了,刚才电脑上多了一个不动的鼠标指针,然后打开显卡管理界面就没了 #include<iostream ...

  9. [HNOI2009]图的同构

    Description 求两两互不同构的含n个点的简单图有多少种. 简单图是关联一对顶点的无向边不多于一条的不含自环的图. a图与b图被认为是同构的是指a图的顶点经过一定的重新标号以后,a图的顶点集和 ...

随机推荐

  1. js验证:密码只能为大写字母+小写字母+数字的8至15位字符组合

    var reg = /^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[a-zA-Z0-9]{8,15}$/; // alert(password); if(reg.test(pa ...

  2. django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.的解决办法

    如题,这个错误的解决办法如下: 在代码文件的最上方添加以下代码: import os,django os.environ.setdefault("DJANGO_SETTINGS_MODULE ...

  3. golang 导出CSV文件中文乱码的问题

    golang  导出CSV文件中文乱码的问题 解决办法: 在csv文件的开头写入 UTF-8 BOM // 创建文件 dstf, err := os.Create("./data/" ...

  4. Failure to find com.oracle:ojdbc6:jar:11.2.0.1.0

    报错原因:oracle的ojdbc.jar是收费的,maven的中央仓库是没有的,需要下载到本地,然后打包进maven仓库 1.下载ojdbc6-11.2.0.1.0.jar包 http://cent ...

  5. linux文件属性软链接

    linux里的软链接 相当于windows系统中的快捷方式 软链接总结: 1.删除源文件,软链接文件依然存在,但是无法访问指向源文件路径内容. 2.失效时候一般是白字红底闪烁显示. test -> ...

  6. 堆排序 && Kth Largest Element in an Array

    堆排序 堆节点的访问 通常堆是通过一维数组来实现的.在数组起始位置为0的情形中: 父节点i的左子节点在位置(2*i+1); 父节点i的右子节点在位置(2*i+2); 子节点i的父节点在位置floor( ...

  7. 牛客练习赛46 E 华华和奕奕学物理 (树状数组)

    https://ac.nowcoder.com/acm/contest/894/E 一开始写了一个简单的模拟 通过率只有5%...... 看题解真的理解了好久!!肥宅大哭orz 题解如下 最后一句:“ ...

  8. (3.4)常用知识-char与varchar的选择

    1.char与varchar的比较 (1)数据存储开销 [1]varchar列需要2个额外的字节来记录存储数据的长度 [2]每个可为null的char列,需要一些字节(空位图)来反应数据的为空性 [3 ...

  9. java8--- (Function、Predicate、Consumer) 通用函数式接口

    // public static void main(String[] args) throws InterruptedException { // https://blog.csdn.net/u01 ...

  10. 消息中间件 JMS入门

    1. JMS入门 1.1消息中间件 什么是消息中间件 消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成.通过提供消息传递和消息排队模型,它可以在分布式环 ...