【BZOJ1478】Sgu282 Isomorphism Pólya定理神题

【BZOJ1478】Sgu282 Isomorphism

题意:用$m$种颜色去染一张$n$个点的完全图,如果一个图可以通过节点重新标号变成另外一个图,则称这两个图是相同的。问不同的染色方案数。答案对$P$取模。
$n\le 53,m\le 1000,P>n,P$是质数。
题解:对于本题来说,每个元素是所有边,每个置换是边的置换,而边的置换难以表示,点的置换容易表示,所以我们考虑点置换和边置换的关系。
如果两个点置换有着相同的结构,则它们对应的边置换的循环数相同。
$$\begin{pmatrix}1&2&3 \ 2&1&3\end{pmatrix}\rightarrow\begin{pmatrix}(1,2)&(1,3)&(2,3) \ (1,2)&(2,3)&(1,3)\end{pmatrix}$$
$$\begin{pmatrix}1&2&3 \ 1&3&2\end{pmatrix}\rightarrow\begin{pmatrix}(1,2)&(1,3)&(2,3) \ (1,3)&(1,2)&(2,3)\end{pmatrix}$$
一个点置换的结构:在表示成循环节时,循环的大小依次为$L_1,L_2,...L_K$。
$L_1,L_2,...L_K$可以组成一个$n$的划分。
而当$n$=53时,$n$个划分数不超过$300000$。
可以通过搜索得出。
那么一个结构为$L_1,L_2,...L_K$的点置换对应边置换的循环数是什么呢?
对于端点在不同点循环中的边,设两端点所在点循环大小为$L_1,L_2$,则这样的边一共有$L_1\times L_2$条,而每个循环有$lcm(L_1,L_2)$条边,所以一共有$gcd(L_1,L_2)$个循环。
对于端点在同一点循环中的边,设所在点循环的大小为$L$,这样的边一共有$C_L^2$条。然后分奇偶讨论:

  1. 如果$L$是奇数,那么一个循环中有$L$条边,所以循环数为${C_L^2\over L}={L-1\over 2}$。
  2. 如果$L$是偶数,那么一个循环中有$L$条边,但是如果两端点相隔$L\over 2$,这个循环中有$L\over 2$条边。所以循环数为${C_L^2-{L\over 2}\over L}+1={L\over 2}$。

所以一个大小为$L$的点循环中边循环的数量是$\lfloor{L\over 2}\rfloor$。
结构为$L_1,L_2,...L_K$的点置换中边循环的数量就是
$$\sum\limits_{i=1}^n\lfloor{L_i\over 2}\rfloor+\sum\limits_{i=1}^K\sum\limits_{j=1}^{i-1}gcd(L_i,L_j)$$
那么有多少结构为$L_1,L_2...L_K$的点置换呢?可以先求出$n!\over {L_1!L_2!...L_K!}$得到每个点属于哪个循环的方案数,而对于每个循环,我们可以先确定第一个点,然后其余点任意排列,方案数是$(L_1-1)!(L_2-1)!...(L_K-1)!$。乘起来得到$n!\over {L_1L_2...L_k}$。
又由于存在一些$L$相等的情况,设有$t$种本质不同的$L$,每种个数为$B_i$,所以总方案数还要除掉$B_1!B_2!...B_t!$,所以总数为:
$$n!\over L_1L_2...L_KB_1!B_2!...B_t!$$
最后套上Pólya定理,令$c=\sum\limits_{i=1}^n\lfloor{L_i\over 2}\rfloor+\sum\limits_{i=1}^K\sum\limits_{j=1}^{i-1}gcd(L_i,L_j)$,$s={n!\over L_1L_2...L_KB_1!B_2!...B_t!}$,答案就是
$$\frac 1 {n!}\sum s\times m^c$$

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
ll P,ans;
int n,m;
ll jc[70],jcc[70],ine[70],pw[3700];
int g[70][70],v[70];
inline int rd()
{
    int ret=0,f=1;  char gc=getchar();
    while(gc<'0'||gc>'9')   {if(gc=='-')    f=-f;   gc=getchar();}
    while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
    return ret*f;
}
inline ll C(int a,int b)
{
    if(a<b) return 0;
    return jc[a]*jcc[a-b]%P*jcc[b]%P;
}
void dfs(int len,int sum)
{
    if(!sum)
    {
        ll s=jc[n],c=0;
        int i,j,tmp;
        for(i=1,tmp=0;i<=len;i++)
        {
            tmp++;
            if(i==len||v[i]!=v[i+1])    s=s*jcc[tmp]%P,tmp=0;
            s=s*ine[v[i]]%P;
            c+=v[i]>>1;
            for(j=1;j<i;j++)    c+=g[v[j]][v[i]];
        }
        ans=(ans+pw[c]*s)%P;
        return ;
    }
    for(int i=min(sum,v[len]);i>=1;i--) v[len+1]=i,dfs(len+1,sum-i);
}
int main()
{
    n=rd(),m=rd(),P=rd();
    int i,j;
    for(pw[0]=i=1;i<=n*n/2;i++) pw[i]=pw[i-1]*m%P;
    for(i=0;i<=n;i++)   g[i][0]=i;
    for(i=0;i<=n;i++)   for(j=1;j<=i;j++)   g[i][j]=g[j][i%j];
    jc[1]=ine[1]=jcc[1]=jc[0]=ine[0]=jcc[0]=1;
    for(i=2;i<=n;i++)   jc[i]=jc[i-1]*i%P,ine[i]=P-(P/i)*ine[P%i]%P,jcc[i]=jcc[i-1]*ine[i]%P;
    v[0]=n;
    dfs(0,n);
    printf("%lld",ans*jcc[n]%P);
    return 0;
}

原文地址:https://www.cnblogs.com/CQzhangyu/p/8227372.html

时间: 2024-10-14 13:35:36

【BZOJ1478】Sgu282 Isomorphism Pólya定理神题的相关文章

BZOJ1478 Sgu282 Isomorphism

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

POJ 2484 A Funny Game(神题!)

一开始看这道博弈题的时候我就用很常规的思路去分析了,首先先手取1或者2个coin后都会使剩下的coin变成线性排列的长条,然后无论双方如何操作都是把该线条分解为若干个子线条而已,即分解为若干个子游戏而已,我想起刘汝佳的大白书上有类似的例题(不过复杂好多),于是便用同样的方法去做了,以sg(x)表示当前连续x个coin的状态的sg函数值,则当从左侧起分别取一个或相邻的两个时,不难得出其后继状态:sg(y)^sg(x-1-y)(0<=y<=(x-1)/2),sg(y)^sg(x-2-y)(0<

CodeForces 171F(千古神题。。)

 D - 乐 Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 171F Description qd ucyhf yi q fhycu dkcruh mxeiu huluhiu yi q tyvvuhudj fhycu dkcruh. oekh jqia yi je vydt jxu djx ucyhf. Input j

UVALive 4487 Exclusive-OR 加权并查集神题

已知有 x[0-(n-1)],但是不知道具体的值,题目给定的信息 只有 I P V,说明 Xp=V,或者 I P Q V,说明 Xp ^ Xq=v,然后要求回答每个询问,询问的是 某任意的序列值 Xp1^Xp2,,,,X^pk 这个题目用加权并查集是这么处理的: 1. f[]照样是代表父节点,照样进行路径压缩,把每个 V[i]=V[i]^V[f[i]],即节点存储的值实际是它与它父亲的异或的值.为什么要这样呢,因为异或首先满足交换律,而且异或同一个数偶数次,即相当于本身,那么这个题目的其中一个要

POJ 2828 Buy Tickets(神题!线段树or树状数组)

题目链接:POJ 2828 Buy Tickets [题意]给了你 n(1<=n<=200000)个人的插队信息,让你输出最终的队列的排列 [思路]常规思考的话,这道题就是模拟,但是时间复杂度一定会很高.POJ的discuss上说这道题是神题,难得不是用什么数据结构,而是思路,这道题要逆向去思考,从最后一个人往前看,后插进来的人更容易定位,他一定能站到他想的位置,并且不会在挪动.再前一个人呢?他的位置即是接下来的空位的编号.于是有线段树用于维护位置信息.当然用树状数组也是可以做的,但是要加上二

Bzoj 4408: [Fjoi 2016]神秘数 可持久化线段树,神题

4408: [Fjoi 2016]神秘数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 177  Solved: 128[Submit][Status][Discuss] Description 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13}, 1 = 1 2 = 1+1 3 = 1+1+1 4 = 4 5 = 4+1 6 = 4+1+1 7 = 4+1+1+1 8无法表示为集合S的子集的

sgu208:Toral Tickets(P&#243;lya定理)

题意简述:给你N和M,对于一个N?M的单面方格纸你可以对它的每 个个格子黑白染色,然后把方格纸的长边卷起来,卷成一个圆柱体,然后再把 两个短边形成的圆也接起来,形成一个游泳圈的形状(我们染的色只在游泳圈 的外表面).如果对于两种黑白染色方案,通过卷成这样的游泳圈后,是一样 的,则这两种方案也是一样的.给定N,M<=20,求染色方案总数. 分析: 首先我们得会Pólya定理,参见http://wenku.baidu.com/view/bf92a95f804d2b160b4ec0be.html 根据

HDOJ Guess the number 3337【神题-抓取杭电后台输出数据】

Guess the number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7077    Accepted Submission(s): 1626 Problem Description AekdyCoin is the most powerful boy in the group ACM_DIY, whose signatur

【POJ2409】Let it Bead P&#243;lya定理

[POJ2409]Let it Bead 题意:用$m$种颜色去染$n$个点的环,如果两个环在旋转或翻转后是相同的,则称这两个环是同构的.求不同构的环的个数. $n,m$很小就是了. 题解:在旋转$i$次后,循环节的个数显然是$gcd(i,n)$. 如果考虑翻转,我们将点从$0$到$n-1$标号,令其先以0到圆心的连线为对称轴翻转,再旋转i次,则原来编号为x的会变成$n-x+i?\mathrm{mod}?n$,令$n-x+i=x?\mathrm{mod}?n$,则$2x=i$或$2x=n+i$.