题目链接

题意

求 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. .NET中使用EF6与连接MYSQL

    ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案,不仅支持SQL Server,还支持MySQL.Ora ...

  2. oracle-控制文件的备份和恢复

    本篇将介绍各种备份及恢复控制文件的方法,在介绍恢复时,以备份和重做日志(包括归档日志和在线日志)没有丢失为前提. 无备份情况下的控制文件恢复参考13.3,丢失重做日志的情况请参考12篇“不完全数据库恢 ...

  3. 【MM系列】SAP MM模块-BOM展开函数

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP MM模块-BOM展开函数   ...

  4. python调用java所有代码都要放在jvm开启的时候调用,否则报错: No matching overloads found for in find. at native\common\jp_method.cpp:127

    1.解决方法 开启java虚拟机 jvm 或者先执行结束在关闭java虚拟机jvm

  5. java 多线程并发问题总结

    java 多线程并发主要通过关键字synchronized实现 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问 ...

  6. P1074 靶形数独 dfs+预处理

    https://www.luogu.org/problemnew/show/P1074 显然是dfs 而且没有什么剪枝记忆化之类的 但是预处理比较麻烦 我用三个二维数组存状态:visx[x][i]代表 ...

  7. sql limit order by and where

    1 sql limit limit size,返回前size行. limit offset , size,返回offset开始的size行,offset从0行开始. 2 sql limit with ...

  8. (4.24)【mysql、sql server】分布式全局唯一ID生成方案

    参考:分布式全局唯一ID生成方案:https://blog.csdn.net/linzhiqiang0316/article/details/80425437 分表生成唯一ID方案 sql serve ...

  9. Mysql 5.7存储过程的学习

    存储过程:对sql的封装和重用,经编译创建并保存在数据库中,通过指定存储过程的名字并给定参数(需要时)来调用执行. 优缺点: (1) 优点: 执行速度快------存储过程只在创建时进行编译,以后每次 ...

  10. Spark-Core RDD转换算子-双Value型交互

    1.union(otherDataSet) 作用:求并集. 对源 RDD 和参数 RDD 求并集后返回一个新的 RDD scala> val rdd1 = sc.parallelize(1 to ...