【BZOJ1488】[HNOI2009]图的同构计数
题意
求 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)\) 种等价类。
这样我们就算完一种类型的置换的贡献了,显然这样的置换是有许多个的,我们还要乘上一个系数,也就是满足我们整数拆分中枚举的格式的置换个数 , 考虑一个排列然后把重复的去掉即可,总数为:
\]
\(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]图的同构计数的更多相关文章
- bzoj1488 [HNOI2009]图的同构 Burnside 引理
题目传送门 bzoj1488 - [HNOI2009]图的同构 bzoj1815 - [Shoi2006]color 有色图(双倍经验) 题解 暴力 由于在做题之前已经被告知是 Burnside 引理 ...
- bzoj1488[HNOI2009]图的同构
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1488 1488: [HNOI2009]图的同构 Time Limit: 10 Sec M ...
- [bzoj1488][HNOI2009]图的同构——Polya定理
题目大意 求两两互不同构的含n个点的简单图有多少种. 简单图是关联一对顶点的无向边不多于一条的不含自环的图. a图与b图被认为是同构的是指a图的顶点经过一定的重新标号以后,a图的顶点集和边集能完全与b ...
- 【BZOJ1488】[HNOI2009]图的同构(Burside引理,Polya定理)
[BZOJ1488][HNOI2009]图的同构(Burside引理,Polya定理) 题面 BZOJ 洛谷 题解 求本质不同的方案数,很明显就是群论这套理论了. 置换一共有\(n!\)个,考虑如何对 ...
- BZOJ 1488 Luogu P4727 [HNOI2009]图的同构 (Burnside引理、组合计数)
题目链接 (Luogu) https://www.luogu.org/problem/P4727 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.ph ...
- [BZOJ1815&BZOJ1488]有色图/图的同构(Polya定理)
由于有很多本质相同的重复置换,我们先枚举各种长度的点循环分别有多少个,这个暴搜的复杂度不大,n=53时也只有3e5左右.对于每种搜索方案可以轻易求出它所代表的置换具体有多少个. 但我们搜索的是点置换组 ...
- 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图的顶点集和 ...
随机推荐
- 【python】集合 list差集|并集|交集
两个list差集 list(set(b).difference(set(a))) # b中有而a中没有的 示例: a=[1,2,3] b=[2,3] list(set(a).difference(se ...
- lnmp 安装yarn
Linux 安装 curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/y ...
- Java多线程学习——wait方法(管道法/生产者消费者模式)
简单介绍管道法: 生产者生产数据输送到管道,消费者从管道拿出数据,管道为空消费者等待,管道满生产者生产,消费者消费生产者生产,生产者生产消费者消费. public class Corn { //要生产 ...
- R-CNN, Fast R-CNN, Faster R-CNN, Mask R-CNN
最近在看 Mask R-CNN, 这个分割算法是基于 Faster R-CNN 的,决定看一下这个 R-CNN 系列论文,好好理一下 R-CNN 2014 1. 论文 Rich feature hie ...
- 【Qt开发】V4L2 API详解 Camera详细设置
Camera的可设置项极多,V4L2 支持了不少.但Sam之前对这些设置的用法和涵义都是在看videodev2.h中边看边理解,感觉非常生涩.直到写这篇blog时,才发现v4l2有专门的SPEC来说明 ...
- JSP总结(jsp/EL表达式/核心标签)
1.概念 jsp,即java Server Pages,java服务器页面. 2.简单介绍 小示例 <%@ page language="java" contentType= ...
- 网络 osi七层协议
一 互联网的本质 咱们先不说互联网是如何通信的(发送数据,文件等),先用一个经典的例子,给大家说明什么是互联网通信. 现在追溯到八九十年代,当时电话刚刚兴起,还没有手机的概念,只是有线电话,那么此时你 ...
- 数学: HDU1098 Ignatius's puzzle
Ignatius's puzzle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- win10无法开启网络发现怎么办 如何启用网络发现
鼠标右键点击桌面左下角的开始按钮,在弹出的菜单中选择“运行”菜单项. 在打开的Windows10运行窗口中,输入Services.msc,然后点击确定按钮. 在打开的Windows10服务窗口 ...
- linux:服务器代理squid安装配置
国内上往外的网站太慢,配了个香港代理服务器.如下:当前环境: centos系统.香港服务器IP(假设:59.188.71.11)检查squid是否安装:[root@localhost ~]# rpm ...