Sgu282 Isomorphism

Description

给定一个N 个结点的无向完全图( 任意两个结点之间有一条边), 现在你可以用 M 种颜色对这个图的每条边进行染色,每条边必须染一种颜色。 若两个已染色的图,其中一个图可以通过结点重新编号而与另一个图完全相同

, 就称这两个染色方案相同。 现在问你有多少种本质不同的染色方法,输出结果 mod P。P 是一个大于N 的质数

Input

仅一行包含三个数,N、M、P。

1≤N≤53,1≤M≤1000

Output

仅一行,为染色方法数 mod P 的结果。

Sample Input

3 4 97

Sample Output

20

polya神题,神题,神题,重要的事情说三遍……

这道题真TM毒瘤,我写了好久,还是不会……只有看题解,不得不说那些大佬真的牛逼。

好,废话不多说,我们进入正题。

这题显然是需要用polya的,但是总置换数到了\(N!\)(我的死因),显然简单的枚举是不可行的,因此我们得换种思想

我们考虑一对点的置换:

  • 点\(i\)和点\(j\)同属于一个长度为\(L\)的循环节中,那么这样的边\((i,j)\)组成的置换中循环节个数显然为\(\lfloor\frac{L}{2}\rfloor\)(考虑隔一个连,隔两个连……即可)
  • 点\(i\)和点\(j\)各属于长\(L_{i}\)和\(L_{j}\)的两个不同循环中,那么这样的边\((i,j)\)组成的循环节的个数为\(lcm(L_{i},L_{j})\)

我们设\(L_{1}\geqslant L_{2}\geqslant ...\geqslant L_{m}>0\),且有\(L_{1}+L_{2}+...+L_{m}=N\),因此,\(L_{i}\)即为\(N\)的一个拆分,而且循环数均为关于\(L_{i}\)的一个函数

由于\(N\leqslant 53\),所以对\(N\)的划分我们可以暴力回溯,然后对于每一种划分我们只要求出对应的置换个数和每个置换的循环节个数

循环节个数我们已知了,置换个数呢?

假定我们已经确定了\(L_{1}\geqslant L_{2}\geqslant ...\geqslant L_{m}>0\),接下来我们只要将\(1...N\)这\(N\)个点分别放入这\(m\)个循环节中,满足第\(i\)个循环中有\(L_{i}\)个点,这便是个简单的组合问题,共\(\dfrac{N!}{L_{1}!L_{2}!...L_{m}!}\)种不同的方式

对于每个循环,确定了第一个点,那么剩下的各点的排列所对应的置换也是不同的,所以还要乘上个\((L_{1}-1)!(L_{2}-1)!...(L_{m}-1)!\)

如果有\(L_{i}=L_{i+1}=...=L_{j}\)的话,那么有\((j-i+1)!\)种方案又是重复的,便要除上一个\((j-i+1)!\)

所以置换的个数就是

\[\frac{N!}{L_{1}L_{2}...L_{m}k_{1}!k_{2}!...k_{t}!}\]

其中,\(t\)表示有\(t\)种不同的\(L\)值,每种值有\(k_{i}\)个

至此,我们就可以完美地解决这道题了

/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
    int x=0,f=1;char ch=getchar();
    for (;ch<‘0‘||ch>‘9‘;ch=getchar())    if (ch==‘-‘)    f=-1;
    for (;ch>=‘0‘&&ch<=‘9‘;ch=getchar())  x=(x<<1)+(x<<3)+ch-‘0‘;
    return x*f;
}
inline void print(int x){
    if (x>=10)     print(x/10);
    putchar(x%10+‘0‘);
}
const int N=1e3;
int fac[N+10],num[N+10],cnt[N+10];
int n,m,p,tot,Ans;
ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}
int mlt(ll a,ll b){
    int res=1;a%=p;
    for (;b;b>>=1,a=1ll*a*a%p)    if (b&1)    res=1ll*res*a%p;
    return res;
}
void dfs(int now,int left){
    if (!left){
        ll a=1,b=0;
        for (int i=1;i<=tot;i++){
            a=a*mlt(num[i],cnt[i])%p*fac[cnt[i]]%p; //快速计算L和k!
            b+=cnt[i]*(cnt[i]-1)/2*num[i]+num[i]/2*cnt[i];
            //这些数gcd都相同,共有k*(k-1)种组成方法,然后计算在同一个循环节的情况
            for (int j=i+1;j<=tot;j++)   b+=cnt[i]*cnt[j]*gcd(num[i],num[j]);    //计算与之后的点不在同一个循环节的情况
        }
        a=1ll*mlt(a,p-2)*fac[n]%p;
        Ans=(Ans+1ll*a*mlt(m,b)%p)%p;
    }
    if (now>left)    return;
    dfs(now+1,left);    //拆分,不选数
    for (int i=1;i*now<=left;i++){//拆分,选数
        num[++tot]=now,cnt[tot]=i;
        dfs(now+1,left-i*now);
        tot--;
    }
}
int main(){
    n=read(),m=read(),p=read(),fac[0]=1;
    for (int i=1;i<N;i++)    fac[i]=1ll*fac[i-1]*i%p;
    //枚举阶乘,方便计算k!
    dfs(1,n);
    Ans=1ll*Ans*mlt(fac[n],p-2)%p;  //逆元
    printf("%d\n",Ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Wolfycz/p/8516888.html

时间: 2024-10-14 13:55:04

Sgu282 Isomorphism的相关文章

BZOJ1478 Sgu282 Isomorphism

Problem A: Sgu282 Isomorphism Time Limit: 15 Sec  Memory Limit: 64 MBSubmit: 172  Solved: 88[Submit][Status][Discuss] Description 给 定一个N 个结点的无向完全图( 任意两个结点之间有一条边), 现在你可以用 M 种颜色对这个图的每条边进行染色,每条边必须染一种颜色. 若两个已染色的图,其中一个图可以通过结点重新编号而与另一个图完全相同, 就称这两个染色方案相同. 现

【BZOJ1478】Sgu282 Isomorphism P&#243;lya定理神题

[BZOJ1478]Sgu282 Isomorphism 题意:用$m$种颜色去染一张$n$个点的完全图,如果一个图可以通过节点重新标号变成另外一个图,则称这两个图是相同的.问不同的染色方案数.答案对$P$取模. $n\le 53,m\le 1000,P>n,P$是质数. 题解:对于本题来说,每个元素是所有边,每个置换是边的置换,而边的置换难以表示,点的置换容易表示,所以我们考虑点置换和边置换的关系. 如果两个点置换有着相同的结构,则它们对应的边置换的循环数相同. $$\begin{pmatri

组合计数(polya计数):SGU 282 Isomorphism

因为论文的题解写得太好了,直接贴. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 typedef long long LL; 6 const int N=55;int st[N]; 7 LL n,m,Mod,fac[N],ifac[N],pow[N],ans; 8 LL Inv(LL x){return x==1?x:(Mod-Mod/x)*

graph isomorphism 开源算法库VFlib, Nauty

VFlib 开源算法库网站:http://www.cs.sunysb.edu/~algorith/implement/vflib/implement.shtml Nauty 开源算法库网站:http://cs.anu.edu.au/people/bdm/nauty/

ZOJ - 4089 :Little Sub and Isomorphism Sequences (同构 set)

Little Sub has a sequence . Now he has a problem for you. Two sequences of length and of length are considered isomorphic when they meet all the following two conditions: ; Define as the number of times integer occur in sequence . For each integer in

ZOJ-4089-Little Sub and Isomorphism Sequences

给定你个数组,以及一些单点修改,以及询问,每次询问需要求得,最长的字串长度,它在其他位置存在同构. 当存在两个不相交的区间同构时,如: 1.2.…….n -1.n.n + 1.…….m.m + 1.m + 2. …….m + n - 1.m + n;(假设m > n&&[1, n]和[m + 1, m + n]同构) 那么 K = n 显然是存在的.但是这不是最大的K,因为[1, m]和[n + 1, n + m]也一定同构(使两边同时加上一个相同区间) 所以这题可以简化为找到一个区

HDU3926Hand in Hand(搜索 或 并查集)

Problem Description In order to get rid of Conan, Kaitou KID disguises himself as a teacher in the kindergarten. He knows kids love games and works out a new game called "hand in hand". Initially kids run on the playground randomly. When Kid say

【转】编程词汇

很实用的编程英语词库,共收录一千五百余条词汇. 第一部分: application 应用程式 应用.应用程序 application framework 应用程式框架.应用框架 应用程序框架 architecture 架构.系统架构 体系结构 argument 引数(传给函式的值).叁见 parameter 叁数.实质叁数.实叁.自变量 array 阵列 数组 arrow operator arrow(箭头)运算子 箭头操作符 assembly 装配件 assembly language 组合语

hdu 3926 Hand in Hand 同构图

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3926 In order to get rid of Conan, Kaitou KID disguises himself as a teacher in the kindergarten. He knows kids love games and works out a new game called "hand in hand". Initially kids run on the p