题意:链接

方法: Polya定理

解析:

先扯点题外话。


小雨淅沥的下午,PoPoQQQ爷在屠了一道题后放松心情,恰看见我把知识点上的群论标记已会。
于是,为了发扬D人的精神,PoPoQQQ爷打开了BZOJ,给我找了这么一个题,说:”这题都没做过还敢说会群论?”
……
……
征战半下午,卒。
(我好菜以后再也不敢说我会啥了T_T


(做这道题千万别去OEIS找通项=-=)

好不扯了,言归正传说这道题怎么做。

这道题确实是个好题,跟以前的群论的解法有共同点但是又有新的东西。

反正我他妈是没推出来。太难辣。

首先题意既然是求不同构的图的个数。

并且点可以任意置换。

所以我们可以这么想这道题。

即所有的边,选取为1,不选取为0。

这就是个染色问题吗。

然后再上个Polya什么的就搞定了。

然而发现,这他妈不对啊。

我们可?求?点的置换,边怎么办啊!

点的置换显然n!,即全排列。

但是边呢!

然后我就死在这里了。

怎么找呢?

不急,我们先来看点的选法。

首先我们肯定能给这个n个点划分一下。

划分成若干部分,每一部分之间可以互相置换。

好像说的有点扯?

其实就是我们来划分一下循环。

每一种划分是一个置换。

然后我们来考虑边,

对于一条边。

它的两个顶点要么是在同一个循环内,要么是在两个循环内。

如下是一个点循环为5的图,显然图中的红色边集体是一个边循环,绿色边集体是一个边循环。

这个画画图就出来了。

其实要证好像也不难?

首先最外层的一堆边肯定是一个循环。

然后我们隔一个连边又是一个循环。

隔两个又是..

直到什么时候呢?

比如这个五边形。

当我们隔两个连的时候就相当于反向连了一个隔一个地边。

这显然之前已经连过了,所以就没有增广循环了。

那么我们就得出来了一个结论,对于在同一个点循环内部的边循环个数,是点循环大小除2。

那么不在一个点循环内的两个点之间的边呢?

图我只能说我尽力了。

一个点循环大小为6,另一个为3,显然有3个边循环。

所以规律呢?

您画一遍就知道是GCD了。

这样我们就研究完了点循环转化边循环。

N的范围是60,我们要划分N的话据说是10^6数量级的。如果我们暴力搞,是不行的。

所以哪里出问题了呢。

让我们来想一个问题。

对于3个点来说,显然排列有6种,但是呢,其中有三种都是一个大小为1的点循环加上一个大小为2的点循环。

也就是说这个方案我们多枚举了两次。

所以我们要优化掉这个东西的话就差不多了。

怎么实现呢?

我们不妨来枚举当前枚举到的点循环的大小。然后在枚举一下个数。

这样我们枚举的复杂度大概是多少呢?

我只算大概。

那我们就不妨把这个枚举复杂度定为O(∑ni=1i∗log(i))O(\sum_{i=1}^{n}i*log(i))

现在来考虑我们枚举完了之后怎么做。

枚举完了之后,因为颜色只有两种(选边或者不选)

所以我们要统计一下边循环的个数。

怎么统计我上面已经说了。

不妨设统计完是x个边循环。

现在对于我们枚举出来的一个点循环集l1,l2...lm{l_1,l_2...l_m}来说,有多少个这个点循环集呢?

有N!|l1|∗|l2|∗...∗|lm|\frac{N!}{|l_1|*|l_2|*...*|l_m|}

但是注意到,我们枚举出来的点循环集可能有大小相等的。

所以我们还得除掉大小相等的点循环集的个数的排列。

至于如上为什么是这样,您要是不知道的话,那请听一听排列组合吧。

于是对应的这个点循环搞出来的如此的边循环集个数是多少呢N!|l1|∗|l2|∗...∗|lm|∗|S1!|∗|S2!|∗...∗|Sq!|\frac{N!}{|l_1|*|l_2|*...*|l_m|*|S_1!|*|S_2!|*...*|S_q!|}

S的定义上文我已经说过了。

然后加上polya定理就搞定了。

但是总置换个数是多少呢?(全排列)

N!…

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1010
#define mod 997
using namespace std;
int n,cnt,ans;
int powtwo[N],factor[N],invfac[N],num[N],val[N],gcd[N][N],inv[N];
int get_gcd(int x,int y)
{while(y){int t=y;y=x%y;x=t;}return x;
}
int get_inv(int x,int y)
{int ret=1;while(y){if(y&1)ret=(ret*x)%mod;x=(x*x)%mod;y>>=1;}return ret;
}
void init()
{powtwo[0]=factor[0]=invfac[0]=1;for(int i=1;i<=mod;i++){factor[i]=factor[i-1]*i%mod;}
}
void dfs(int now_num,int left)
{if(left==0){int retnow=0;int bot=1;for(int i=1;i<=cnt;i++){retnow+=num[i]*(num[i]-1)/2*val[i]+val[i]/2*num[i];for(int j=i+1;j<=cnt;j++)retnow+=num[i]*num[j]*get_gcd(val[i],val[j]);}for(int i=1;i<=cnt;i++){bot=(bot*get_inv(val[i],num[i])%mod*factor[num[i]])%mod; } bot=get_inv(bot,mod-2)*factor[n]%mod; ans=(ans+get_inv(2,retnow)*bot%mod)%mod; }if(now_num>left)return;dfs(now_num+1,left);for(int i=1;i*now_num<=left;i++){val[++cnt]=now_num,num[cnt]=i;dfs(now_num+1,left-i*now_num);cnt--;}
}
int main()
{scanf("%d",&n);init();dfs(1,n);ans=ans*get_inv(factor[n],mod-2)%mod;printf("%d\n",ans);
} 

BZOJ 1488 [HNOI2009]图的同构 Polya定理相关推荐

  1. [BZOJ1815BZOJ1488]有色图/图的同构(Polya定理)

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

  2. BZOJ1488: [HNOI2009]图的同构

    BZOJ1488: [HNOI2009]图的同构 Description 求两两互不同构的含n个点的简单图有多少种. 简单图是关联一对顶点的无向边不多于一条的不含自环的图. a图与b图被认为是同构的是 ...

  3. 置换群Polya定理(poj 2409: Let it Bead)

    可以先看 置换群burnside引理(bzoj 1004: [HNOI2008]Cards) Polya定理公式(必须在没有限制下才能使用此公式): 其中|G|为总置换数,m表示可用的颜色数,c(gi ...

  4. (每日一题)P4128 [SHOI2006] 有色图(文末有色图!)(Polya定理)(超级详细,清晰易懂)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 每日一题(莫反 / 多项式 / 母函数 / 群论) 2021.4.13 群论 嘿嘿嘿,本题题名为 有涩 ...

  5. 置换群和Burnside引理,Polya定理

    定义简化版: 置换,就是一个1~n的排列,是一个1~n排列对1~n的映射 置换群,所有的置换的集合. 经常会遇到求本质不同的构造,如旋转不同构,翻转交换不同构等. 不动点:一个置换中,置换后和置换前没 ...

  6. poj2154Color polya定理+欧拉函数优化

    没想到贱贱的数据居然是错的..搞得我调了一中午+晚上一小时(哦不d飞LJH掉RP毕竟他是BUFF)结果重判就对了五次.. 回归正题,这题傻子都看得出是polya定理(如果你不是傻子就看这里),还没有翻 ...

  7. Burnside引理和Polya定理学习笔记

    前言 求·······的方案数 循环同构算一种 一脸懵逼 (于是我觉得系统的学一遍Burnside引理和Polya定理) 正文 置换 置换的概念 对于一个排列aia_iai​ 我们想成iii输进去会出 ...

  8. POJ 2409 Let it Bead (Polya定理)

    题意 用k种颜色对n个珠子构成的环上色,旋转翻转后相同的只算一种,求不等价的着色方案数. 思路 Polya定理 X是对象集合{1, 2, --, n}, 设G是X上的置换群,用M种颜色染N种对象,则不 ...

  9. poj2154 Color ——Polya定理

    题目:http://poj.org/problem?id=2154 今天学了个高端的东西,Polya定理... 此题就是模板,然而还是写了好久好久... 具体看这个博客吧:https://blog.c ...

最新文章

  1. 10个比较艰难的Java面试题与答案!
  2. mysql repair 索引_mysql 创建索引、重建索引、查询索引、删除索引 转自:http://www.phpernote.com/mysql/942.html...
  3. PostgreSQL 创建库时如何指定 Collate, Ctype
  4. Mysql基础知识:索引
  5. Hibernate generator小结
  6. Linux命令之感叹号 !
  7. JS数据结构学习之排序
  8. GIF 太大?用 GIFSicle
  9. 红黑树并没有我们想象的那么难(下)
  10. ping命令使用集合
  11. Intellij idea 2018.3热部署 jrebel 激活
  12. 架构师到底该不该写代码?
  13. 理解Creating network “projectName_default” with the default driver
  14. 华为快应用IDE:如何使用华为快应用IDE进行快应用测试
  15. spin_lock详解
  16. 浅谈搜狐云景PAAS平台
  17. Spring Boot 之 Spring Data JPA(一)
  18. 【福利】SACC 2016 PPT汇总下载
  19. 调查称多地10%大米镉超标 食物污染链持续多年
  20. 移动端完成样式之后出现横向滚动条(X 轴滚动条)

热门文章

  1. 成都国际文创产业园助力成都文创产业腾飞
  2. java集合的遍历删除
  3. “灯塔工厂”亮了吗?
  4. insertBefore()方法,
  5. 路由黑洞与黑洞路由简介
  6. swagger不显示接口的可能性
  7. android自定义radiogroup,Android 自定义View实现任意布局的RadioGroup效果
  8. 微信小程序----------WXML模板文件一
  9. Grails clean
  10. 学习笔记二:OSS上传视频截帧