Atcoder Beginner Contest ABC 284 Ex Count Unlabeled Graphs 题解 (Polya定理)
弱化版(其实完全一样)
u1s1,洛谷上这题的第一个题解写得很不错,可以参考
直接边讲Polya定理边做这题
问题引入:n颗珠子组成的手串,每颗珠子有两种不同的颜色, 如果两个手串能够在旋转或翻转之后完全一样,就称它们是等价的,对手串的等价类计数。我们先把手串破环为链,两个长度为n的01序列等价当且仅当能够在循环移位或翻转后完全一样,求等价类数量。
注意两个序列"相等"指的是外表完全相同,"等价"指的是能够通过转化后外表完全相同。
Polya定理说这个问题的答案是:\(\frac 1{|G|}\sum_{g\in G}c(g,X)\)。其中X表示所有外表不同的序列的集合;G表示把所有变换看成置换之后的置换群(置换群的概念请自行搜索);\(c(g,X)\)表示X中满足"将置换g施加到序列x上之后x的外表仍然不变"的元素x的个数,专业点说是不动点的个数。对于任意置换与等价类计数的问题,都可以用这个式子求。
具体证明可以看这里
对于这道题也是一样,这题中X是所有点有编号、点有权值(1-k)、边有权值(1/0表示存在或不存在)的n个点的无向完全图的集合;G是置换群(由于这题中的变换是给节点重新编号,所以G是所有1-n的排列的集合);\(c(g,X)\)表示X中满足"将置换g施加到无向图x上之后x的外表仍然不变"的元素x的个数。
假设现在我们枚举g,考虑求出\(c(g,X)\)。对于g,如果我们把\(i\to g_i\)连有向边,是可以得到若干环的,假设这些环的大小从小到大排列为\(b_1,b_2\cdots b_m\)。对于其中的一条边\(u\to v\),原图中的节点u在经过变换之后它的编号就要变成v了。考虑如果想让变换前后的图外表完全一样,这个图需要满足什么条件。首先g连出的每一个环内的点权值都必须相同,且所有的环必须覆盖[1,k]中的全部颜色(题目要求,用dp预处理方案数即可)。接下来的限制其实跟上面那个弱化版一样,每个长度为\(b_i\)的环内的所有边被分成了\(\lfloor \frac {b_i}2 \rfloor\)类,每一类的权值都必须相等;两个长度为\(b_i,b_j\)的环之间的\(b_ib_j\)条边被分成了\(gcd(b_i,b_j)\)类,每一类的权值都必须相等。
对于一个序列\(b_1,b_2\cdots b_m\),我们已经能快速地用上面的方法算出它对答案的贡献,现在还要知道有多少个g对应这个序列,其实就是个简单的排列组合问题。令\(c_i\)表示b序列中值i出现的次数。对应这个b序列的g的个数为:\(\frac{n!}{\prod_{i=1}^m, b_i!}\cdot (\prod_{i=1}^m (b_i-1)!)\cdot \frac 1{\prod c_i! }\),其中第一部分为多重组合数,用来选出每个环的元素;第二部分是把每个环中的所有元素排成有序环的方案数;第三部分是除掉相同的\(b_i\)算重的次数。
列一下最后答案的式子:\(ans=\sum_{b_1\cdots b_m} \frac 1{\prod b_i\prod c_i!}\cdot dp_{m,k}\cdot 2^{(\sum \lfloor \frac {b_i}2 \rfloor )+\sum_{i,j}gcd(b_i,b_j)}\),其中\(dp_{i,j}\)表示1-i一共i个元素染色,且占了\([1,j]\)中的所有颜色的方案数。
我们直接暴搜枚举\(b\)数组所有可能的情况,然后用上面的方法暴力计算就行。时间复杂度\(O(能过)\)。
点击查看代码
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define pdd pair <double,double>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back
void fileio()
{
#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
void termin()
{
#ifdef LGS
std::cout<<"\n\nEXECUTION TERMINATED";
#endif
exit(0);
}
using namespace std;
LL n,k,MOD,ans=0,fac[40],inv[40],rinv[40],dp[40][40];
vector <LL> d;
LL qpow(LL x,LL a)
{
LL res=x,ret=1;
while(a>0)
{
if(a&1) (ret*=res)%=MOD;
a>>=1;
(res*=res)%=MOD;
}
return ret;
}
void dfs(LL sum,LL mx)
{
if(sum==n)
{
LL res=1;
rep(i,d.size()) (res*=rinv[d[i]])%=MOD;
map <LL,LL> mp;rep(i,d.size()) ++mp[d[i]];
for(auto it:mp) (res*=inv[it.se])%=MOD;
(res*=dp[d.size()][k])%=MOD;
LL tot=0;
rep(i,d.size()) tot+=d[i]/2;
rep(i,d.size()) for(int j=i+1;j<d.size();++j) tot+=__gcd(d[i],d[j]);
(res*=qpow(2,tot))%=MOD;
(ans+=res)%=MOD;
return;
}
for(LL nxt=max(mx,1LL);nxt<=n-sum;++nxt)
{
d.pb(nxt);
dfs(sum+nxt,nxt);
d.pop_back();
}
}
int main()
{
fileio();
cin>>n>>k>>MOD;
dp[0][0]=1;
rep(i,n+3) rep(j,k+1) if(dp[i][j])
{
(dp[i+1][j]+=dp[i][j]*j)%=MOD;
(dp[i+1][j+1]+=dp[i][j]*(j+1))%=MOD;
}
fac[0]=1;repn(i,35) fac[i]=fac[i-1]*i%MOD;
rep(i,34) inv[i]=qpow(fac[i],MOD-2),rinv[i]=qpow(i,MOD-2);
dfs(0,0);
cout<<ans<<endl;
termin();
}
Atcoder Beginner Contest ABC 284 Ex Count Unlabeled Graphs 题解 (Polya定理)的更多相关文章
- [题解] Atcoder Beginner Contest ABC 270 G Ex 题解
点我看题 G - Sequence in mod P 稍微观察一下就会发现,进行x次操作后的结果是\(A^xS+(1+\cdots +A^{x-1})B\).如果没有右边那一坨关于B的东西,那我们要求 ...
- [题解] Atcoder Beginner Contest ABC 265 Ex No-capture Lance Game DP,二维FFT
题目 首先明确先手的棋子是往左走的,将其称为棋子1:后手的棋子是往右走的,将其称为棋子2. 如果有一些行满足1在2右边,也就是面对面,那其实就是一个nim,每一行都是一堆石子,数量是两个棋子之间的空格 ...
- AtCoder Beginner Contest 053 ABCD题
A - ABC/ARC Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Smeke has ...
- AtCoder Beginner Contest 100 2018/06/16
A - Happy Birthday! Time limit : 2sec / Memory limit : 1000MB Score: 100 points Problem Statement E8 ...
- AtCoder Beginner Contest 076
A - Rating Goal Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Takaha ...
- AtCoder Beginner Contest 068 ABCD题
A - ABCxxx Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement This contes ...
- AtCoder Beginner Contest 161
比赛链接:https://atcoder.jp/contests/abc161/tasks AtCoder Beginner Contest 161 第一次打AtCoder的比赛,因为是日本的网站终于 ...
- AtCoder Beginner Contest 224
AtCoder Beginner Contest 224 A - Tires 思路分析: 判断最后一个字符即可. 代码如下: #include <bits/stdc++.h> using ...
- KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解
KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解 哦淦我已经菜到被ABC吊打了. A - Century 首先把当前年 ...
- AtCoder Beginner Contest 184 题解
AtCoder Beginner Contest 184 题解 目录 AtCoder Beginner Contest 184 题解 A - Determinant B - Quizzes C - S ...
随机推荐
- HTML基础知识(3)浮动、塌陷问题
1.浮动 1.1 代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> & ...
- Dapr实现.Net Grpc服务之间的发布和订阅,并采用WebApi类似的事件订阅方式
大家好,我是失业在家,正在找工作的博主Jerry,找工作之余,总结和整理以前的项目经验,动手写了个洋葱架构(整洁架构)示例解决方案 OnionArch.其目的是为了更好的实现基于DDD(领域驱动分析) ...
- Mysql InnoDB Buffer Pool
参考书籍<mysql是怎样运行的> 系列文章目录和关于我 一丶为什么需要Buffer Pool 对于InnoDB存储引擎的表来说,无论是用于存储用户数据的索引,还是各种系统数据,都是以页的 ...
- Java获取/resources目录下的资源文件方法
Web项目开发中,经常会有一些静态资源,被放置在resources目录下,随项目打包在一起,代码中要使用的时候,通过文件读取的方式,加载并使用: 今天总结整理了九种方式获取resources目录下文件 ...
- 重新整理 .net core 实践篇 ———— dotnet-dump [外篇]
前言 本文的上一篇为: https://www.cnblogs.com/aoximin/p/16861797.html 该文为dotnet-dump 和 procdump 的实战介绍一下. 正文 现在 ...
- springboot集成支付宝的支付(通用版)
[1.引依赖] <dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sd ...
- Optional对象
Optional对象 Optional 类是一个可以为null的容器对象,用于简化Java中对空值的判断处理,以防止出现各种空指针异常. 静态方法-of 必须确定对象不为null 在使用of封装成op ...
- 自动增加 Android App 的版本号
一般的 C# 应用程序中都有一个 AssemblyInfo.cs 文件,其中的 AssemblyVersion attribute 就可以用来设置该应用程序的版本号.譬如, [assembly: As ...
- Winform控件绑定数据
目录 简介 绑定基类 功能扩展 简单控件绑定 列表控件绑定 绑定BindingList集合 绑定DataTable表格 绑定BindingSource源 表格控件绑定 绑定DataTable 绑定Bi ...
- windows使用pyinstaller 打包sklearn模块出现死循环报错
前言 解决这个让我花费了很长时间, 我这里说的死循环,不是正常通过 --hidden-import能解决的问题. 因为我也查询了很多资料 但是无一例外都失败了(能通过 –hidden-import 解 ...