P4128 [SHOI2006]有色图
数学渣渣看题解看得想死Ծ‸Ծ
首先发现这玩意儿看着很像polya定理
\]
然而polya定理只能用来求点的置换,边的置换是布星的
于是我们考虑一个点的置换,把它写成若干循环的乘积\((a_1,a_2,..)(b_1,b_2,...)...\)
1.对于不在同一个循环里的点,比方说一条边\((a_1,b_1)\),那么和它在同一个循环的边有\(((a_1,b_1),(a_2,b_2),...)\)设\(a\)的循环节为\(l_1\),\(b\)的循环节为\(l_2\),那么这个边的循环的循环节长度就是\(lcm(l_1,l_2)\),而总共的边数为\(l_1*l_2\),那么循环的个数就是\(\frac{l_1*l_2}{lcm(l_1,l_2)}=gcd(l_1,l_2)\)
2.对于在同一个循环内的点,设\(a\)的循环节长度为\(l_1\)
如果\(l_1\)长度为奇数,那么循环的长度就是\(l_1\),总共有\(C_{l_1}^{2}\)条边,那么循环的个数就是\(\frac{l-1}2\)
如果\(l_1\)长度为偶数,除了上面的情况之外,还有一种很gg的情况就是比方说\((a_1,a_{l_1/2+1})\)的边所在的循环,这个循环的长度是\(l_1/2\),占的边数为\(l_1/2\),除此之外其他的情况都是一样的,所以循环的个数就是\(\frac{\frac{l(l-1)}{2}-\frac{l}2}{l}+1=\frac l 2\)
那么,总共的边的置换就是
\]
然而如果直接枚举的话复杂度是带一个感叹号的……然而我们只需要知道所有的\(l_i\)就行了,而不需要知道循环里具体是什么数字……所以会T就是我们知道的太多了
于是我们可以枚举\(l_i\),为了不重不漏保证\(l_i\)不降,先考虑如果\(l_i\)互不相同的话有多少种方案。我们可以这样理解,枚举\(n\)个数字的全排列,然后按\(l_i\)从左到右依次分组,那么这样肯定就是一个置换了……然后对于其中的每一个循环\((a_1,a_2,...,a_l)\)来说,\((a_2,a_3,...,a_l,a_1)...\)之类的其实是跟它一样的,也就是说每个循环有\(l_i\)个同构的,所以要除掉,那么方案数就是
\]
然而现在问题是\(l_i\)有可能会相等,如果按上面那样考虑的话有可能会有两个\(l_i\)相等的循环被算到不同的里面了……所以还要设\(B_i\)为\(l_j==i\)的个数,然后除掉他们中间排列的个数,那么方案数应该是
\]
然后dfs暴力找\(l_i\)即可
最后就是
\]
之后就是抄代码了
//minamoto
#include<bits/stdc++.h>
#define int long long
#define fp(i,a,b) for(register int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i)
using namespace std;
const int N=105;
int ans,P,n,m,fac[N],rec[N];
int gcd(int x,int y){return y?gcd(y,x%y):x;}
int ksm(int x,int y){
int res=1;
for(;y;y>>=1,x=x*x%P)if(y&1)res=res*x%P;
return res;
}
void calc(int x){
int sum=0,mul=1,now=1;
fp(i,1,x)sum+=rec[i]/2;
fp(i,1,x)fp(j,i+1,x)sum+=gcd(rec[i],rec[j]);
fp(i,1,x)(mul*=rec[i])%=P;
fp(i,2,x){
if(rec[i]!=rec[i-1])(mul*=fac[now])%=P,now=0;
++now;
}(mul*=fac[now])%=P,mul=fac[n]*ksm(mul,P-2)%P;
(ans+=mul*ksm(m,sum)%P)%=P;
}
void dfs(int k,int x,int s){
if(!x)calc(k-1);if(x<s)return;
fp(i,s,x)rec[k]=i,dfs(k+1,x-i,i);
}
signed main(){
// freopen("testdata.in","r",stdin);
scanf("%lld%lld%lld",&n,&m,&P),fac[0]=1;
fp(i,1,n)fac[i]=fac[i-1]*i%P;
dfs(1,n,1);(ans*=ksm(fac[n],P-2))%=P;
printf("%lld\n",ans);return 0;
}
P4128 [SHOI2006]有色图的更多相关文章
- 洛谷 P4128 [SHOI2006]有色图 解题报告
P4128 [SHOI2006]有色图 题目描述 如果一张无向完全图(完全图就是任意两个不同的顶点之间有且仅有一条边相连)的每条边都被染成了一种颜色,我们就称这种图为有色图.如果两张有色图有相同数量的 ...
- 洛谷 P4128: bzoj 1815: [SHOI2006]有色图
题目传送门:洛谷 P4128. 计数好题,原来是 13 年前就出现了经典套路啊.这题在当年应该很难吧. 题意简述: \(n\) 个点的完全图,点没有颜色,边有 \(m\) 种颜色,问本质不同的图的数量 ...
- [SHOI2006] 有色图
Description 给一张 \(n\) 个点的无向完全图,同时还有 \(m\) 种颜色.要求给每条边染色,问有多少种不同的染色方案.两种方案不同当且仅当顶点标号任意重排后不同.\(n\leq 53 ...
- BZOJ1815 SHOI2006有色图(Polya定理)
置换数量是阶乘级别的,但容易发现本质不同的点的置换数量仅仅是n的整数拆分个数,OEIS(或者写个dp或者暴力)一下会发现不是很大,当n=53时约在3e5左右. 于是暴力枚举点的置换,并且发现根据点的置 ...
- bzoj 1815: [Shoi2006]color 有色图 置换群
1815: [Shoi2006]color 有色图 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 136 Solved: 50[Submit][Stat ...
- BZOJ1815: [Shoi2006]color 有色图
BZOJ1815: [Shoi2006]color 有色图 Description Input 输入三个整数N,M,P 1< = N <= 53 1< = M < = 1000 ...
- BZOJ 1815: [Shoi2006]color 有色图(Polya定理)
题意 如果一张无向完全图(完全图就是任意两个不同的顶点之间有且仅有一条边相连)的每条边都被染成了一种颜色,我们就称这种图为有色图. 如果两张有色图有相同数量的顶点,而且经过某种顶点编号的重排,能够使得 ...
- BZOJ 1815: [Shoi2006]color 有色图 [Polya DFS 重复合并]
传送门 题意: 染色图是无向完全图,且每条边可被染成k种颜色中的一种.两个染色图是同构的,当且仅当可以改变一个图的顶点的编号,使得两个染色图完全相同.问N个顶点,k种颜色,本质不同的染色图个数(模质数 ...
- [SHOI2006]color 有色图[群论、组合计数]
题意 用 \(m\) 种颜色,给 \(n\) 个点的无向完全图的 \(\frac{n(n-1)}{2}\) 条边染色,两种方案相同当且仅当一种方案交换一些点的编号后可以变成另一种方案.问有多少本质不同 ...
随机推荐
- C语言《一维数组的学习,冒泡排序》
#include<stdio.h> /* 一维数组的学习,冒泡排序 soulsjie 20170623 */ void main(){ int a[6]; int i,j,k; print ...
- 用二分法计算a的n次幂<算法分析>
实验目的:1.复习java编程:2.掌握二分法的基本原理:3.掌握使用java程序进行二分法计算a的n次幂.实验步骤:1.由用户输入a及n(均为整数):2.利用二分法完成计算,并将中间结果打印出来. ...
- Linux环境下使用VSCode编译makefile文件的注意事项
Linux环境下使用VSCode编译makefile文件的注意事项 首先安装C/C++的两个依赖 在debug,launch会自动的生成下方的launch.json launch.json { // ...
- 动态规划之最长公共子序列(LCS)
在字符串S中按照其先后顺序依次取出若干个字符,并讲它们排列成一个新的字符串,这个字符串就被称为原字符串的子串 有两个字符串S1和S2,求一个最长公共子串,即求字符串 ...
- 【bzoj2152】聪聪可可 点分治
[bzoj2152]聪聪可可 2014年9月7日3,5472 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是 ...
- 【BZOJ3697】采药人的路径(点分治)
题意:采药人的药田是一个树状结构,每条路径上都种植着同种药材.采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的.采药人每天都要进行采药活动.他选择的路径是很 ...
- redis运维相关(基本数据库命令)【十四】
-----------------------------运维相关------------------------- redis持久化,两种方式1.rdb快照方式2.aof日志方式 --------- ...
- MongoDB小结27 - 聚合管道【$project】
我们有这样的数据 { "_id" : 1, title: "abcdef", isbn: "6969696969", author: { l ...
- 手把手教你开发Chrome扩展三:关于本地存储数据
手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发Chrome扩展二:为html添加行为 手把手教你开发Chrome扩展三:关于本地存储数据 HTML5 ...
- 【c++】【转】c++中的explicit关键字
http://www.cnblogs.com/chio/archive/2007/09/17/895263.html c++中的explicit关键字用来修饰类的构造函数,表明该构造函数是显式(调用) ...