题目链接

https://www.luogu.org/problem/P4708

题解

看上去Luogu P4706-4709是Sdchr神仙出的一场比赛,一道水题和三道很有趣的题终于全过了纪念QAQ(然而后三道都看了题解)
以及为啥这题AC代码几乎全是打表。。

前置题目: BZOJ1488 求\(n\)个点无标号无向图个数。(欢迎阅读 https://www.cnblogs.com/suncongbo/p/11295453.html )
没做过的建议先去做一下那题。

这道题依然是枚举拆分数,然后现在的问题就是给定一些长度的轮换求有多少个点度均为偶数的图满足经过这些轮换作用后依然不变。
首先一个性质是,同一轮换内的所有点度数相同。(显然)
考虑轮换内部的边,假设这个轮换长度为\(L=2s+1\), 那么则有\(s\)种不同的边组,每一种边组会使得轮换内所有点度数\(+2\); 若轮换长度为\(2s\), 则有\(s\)种不同的边组,其中\((s-1)\)种(除了对角的之外)使得所有点度数\(+2\), \(1\)种使得所有点度数\(+1\). 度数\(+2\)不改变奇偶性的显然可以不考虑,直接答案乘以\(2\).
再考虑轮换之间的边,假设两轮换长度分别为\(a,b\)则有\(\gcd(a,b)\)种边组,每种边组内包含\(\text{lcm}(a,b)\)条边,会给\(a\)中的点度数\(+\frac{\text{lcm}(a,b)}{a}\),给\(b\)中的点度数\(+\frac{\text{lcm(a,b)}}{b}\). 若二者都为偶数,答案乘以\(2^{\gcd(a,b)}\). 若二者中恰有一个为奇数,则相当于有\(\gcd(a,b)\)次机会给奇数的那个轮换改变奇偶性。若二者都是奇数,则相当于有\(\gcd(a,b)\)次机会给两个轮换同时改变奇偶性。

于是问题转化为: 有一张新图(新图里的点代表一个轮换),初始点权都为\(0\), 对每个点有\(c_i\)次机会改变它的奇偶性,对每条边有\(d_i\)次机会同时改变两端点的奇偶性。求有多少种方案使得最终所有点的点权为\(0\).
这个结论是,对于每一种改变点权总次数为偶数次的方案,都存在\(2^{\sum d_i-cnt+1}\)种边操作方案(\(cnt\)为点数)与之对应。
感性理解,改变点权如果是奇数次显然不行,偶数次的话可以构建一棵DFS树,非树边任意操作之后树边按照自下而上操作总能操作完。注意这里官方题解写的是错的!官方题解直接写成\(2^{\sum d_i}\)坑了我一晚上……
那么答案就是\(2^{\sum c_i-1}\times 2^{\sum d_i-cnt+1}\).
问题解决。

时间复杂度同BZOJ 1488.

代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<iostream>
#define llong long long
using namespace std;inline int read()
{int x=0; bool f=1; char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=0;for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');if(f) return x;return -x;
}const int N = 50;
const int P = 998244353;
llong fact[N*N*N+3],finv[N*N*N+3],inv[N*N*N+3],pw2[N*N*N+3];
int gcd[N+3][N+3];int GCD(int x,int y) {return y==0 ? x : GCD(y,x%y);}llong quickpow(llong x,llong y)
{llong cur = x,ret = 1ll;for(int i=0; y; i++){if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur%P;}cur = cur*cur%P;}return ret;
}void initmath(int n)
{fact[0] = 1ll; for(int i=1; i<=n; i++) fact[i] = fact[i-1]*i%P;finv[n] = quickpow(fact[n],P-2); for(int i=n-1; i>=0; i--) finv[i] = finv[i+1]*(i+1)%P;for(int i=1; i<=n; i++) inv[i] = finv[i]*fact[i-1]%P;pw2[0] = 1ll; for(int i=1; i<=n; i++) pw2[i] = pw2[i-1]*2ll%P;
}int a[N+3],num[N+3];
int uf[N+3];
int c[N+3];
int n,cnt; llong ans;int findfa(int u)
{int i = u;while(u!=uf[u]) {u = uf[u];}while(u!=uf[i]){int j = uf[i]; uf[i] = u; i = j;}return u;
}void unionfa(int u,int v)
{int x = findfa(u),y = findfa(v);if(x!=y) {uf[x] = y;}
}llong calc()
{for(int i=1; i<=cnt; i++) uf[i] = i,c[i] = 0;llong ret = fact[n];for(int i=1; i<=cnt; i++) {ret = ret*inv[a[i]]%P;}for(int i=1; i<=n; i++) {ret = ret*finv[num[i]]%P;}llong retp = 0ll;for(int i=1; i<=cnt; i++){for(int j=i+1; j<=cnt; j++){int g = gcd[a[i]][a[j]],lcm = a[i]*a[j]/g;int ci = lcm/a[i],cj = lcm/a[j];if((ci&1)==(cj&1)){retp += g;if(ci&1) {unionfa(i,j);}}}}for(int i=1; i<=cnt; i++){for(int j=i+1; j<=cnt; j++){int g = gcd[a[i]][a[j]],lcm = a[i]*a[j]/g;int ci = lcm/a[i],cj = lcm/a[j];int x = findfa(i),y = findfa(j);if((ci&1)!=(cj&1)){if(ci&1) {c[x]+=g;}else if(cj&1) {c[y]+=g;}}}}for(int i=1; i<=cnt; i++){int x = findfa(i);retp += ((a[i]-1)>>1);if(!(a[i]&1)) {c[x]++;}}retp -= cnt;for(int i=1; i<=cnt; i++) {if(uf[i]==i) retp++;}for(int i=1; i<=cnt; i++){if(uf[i]==i && c[i]>0){retp += c[i]-1;}}ret = ret*pw2[retp]%P;return ret;
}void dfs(int sum)
{if(sum==0){ans = (ans+calc())%P;}for(int i=a[cnt]; i<=sum; i++){cnt++; a[cnt] = i; num[i]++;dfs(sum-i);num[i]--; a[cnt] = 0; cnt--;}
}int main()
{initmath(N*N*N);for(int i=1; i<=N; i++) for(int j=1; j<=N; j++) gcd[i][j] = GCD(i,j);scanf("%d",&n);a[0] = 1; dfs(n);ans = ans*finv[n]%P;printf("%lld\n",ans);return 0;
}

Luogu P4708 画画 (Burnside引理、组合计数、划分数)相关推荐

  1. Luogu P4708 画画 (Burnside引理、组合计数)

    题目链接 https://www.luogu.org/problem/P4708 题解 看上去Luogu P4706-4709是Sdchr神仙出的一场比赛,一道水题和三道很有趣的题终于全过了纪念QAQ ...

  2. Luogu P5564 [Celeste-B]Say Goodbye (多项式、FFT、Burnside引理、组合计数)

    题目链接 https://www.luogu.org/problem/P5564 题解 这题最重要的一步是读明白题. 为了方便起见下面设环长可以是\(1\), 最后统计答案时去掉即可. 实际上就相当于 ...

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

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

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

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

  5. 蓝桥杯 结果填空 正六面体染色 Burnside引理

    正六面体用4种颜色染色. 共有多少种不同的染色样式? 要考虑六面体可以任意旋转.翻转. 参考答案: 240 可以想象,这道题如果编程的话,代码不会很少,关键是也没啥思路,其实组合数学早就给我们提供了数 ...

  6. 置换群,Polya引理和burnside引理(等价类计数问题)

    参考文章: 等价类计数问题 Burnside引理&Pólya定理 Burnside引理与Polya定理 置换群和Burnside引理,Polya定理 概念引入: 离散数学应该学过置换群的相关概 ...

  7. 解题报告(五)组合计数(ACM / OI)超高质量题解

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  8. 数学:Burnside引理与Pólya定理

    这个计数定理在考虑对称的计数中非常有用 先给出这个定理的描述,虽然看不太懂: 在一个置换群G={a1,a2,a3--ak}中,把每个置换都写成不相交循环的乘积. 设C1(ak)是在置换ak的作用下不动 ...

  9. 置换群burnside引理(bzoj 1004: [HNOI2008]Cards)

    置换群: 看半天置换群表示并看不懂QAQ 但顾名思义是置换组成的群 其实不用看懂也行,就拿简单的例子来说吧 有一个序列s = {1, 2, 3, 4, 5, 6} 和一个变换规则t = {2, 3, ...

最新文章

  1. 干货丨机器学习知识点(人工智能篇)
  2. python自学路线-Python最佳学习路线
  3. C#规范整理·语言要素
  4. python服务器qt客户端_python3+PyQt5 创建多线程网络应用-TCP客户端和TCP服务器实例...
  5. 怕入错行?这群技术人写了本“择业指南”
  6. NOIP 2010 引水入城
  7. python 列表的增删改查操做1125 元组 的查操做
  8. 【TI-ONE系列教程(一)】如何使用TI-ONE平台
  9. Shell编程入门学习
  10. html黑洞效果,html5黑洞动画特效
  11. python聊天室设计_如何使用 Python 开发一个聊天室?
  12. 有关计算机活动英语作文,有关电脑的英语作文
  13. NCE4 L46 Hobbies
  14. 【代码审计】那些代码审计的思路.md
  15. 视频教程-深度学习与TensorFlow 2入门实战-深度学习
  16. 使用javax.servlet.http.Part类上传文件
  17. 获取windows当前的AD账号
  18. spring boot + shiro 实现登陆 踢出用户功能 (挤人) 以及UnknownSessionException异常问题 记住我功能
  19. NKOJ 3762 守夜人 (并查集)
  20. 动易CMS - 设为首页代码和加入收藏代码(兼容各种浏览器)

热门文章

  1. 云炬Android开发笔记 7登陆注册功能开发
  2. Gateway配合sentinel自定义限流_你知道如何使用阿里Sentinel实现接口限流吗?
  3. 编写代码的若干个基本规则(以Java为例)
  4. Win7下快速预览各种类型的文本文件
  5. c#下简单的文件读写
  6. Ajax里的onreadystatechange的作用
  7. sizeof和gcvt转换双精度函数的函数不是小结的小结
  8. PDGAN: A Novel Poisoning Defense Method in Federated Learning Using Generative Adversarial Network笔记
  9. 【CyberSecurityLearning 68】python 编写exp
  10. BugkuCTF-Misc:又一张图片,还单纯吗