置换数量是阶乘级别的,但容易发现本质不同的点的置换数量仅仅是n的整数拆分个数,OEIS(或者写个dp或者暴力)一下会发现不是很大,当n=53时约在3e5左右。

  于是暴力枚举点的置换,并且发现根据点的置换我们得到的实际上是边的置换,暴力数一下循环节就好了。3e5*50*50,luogu上过掉了。诶怎么bzoj上开的时限总共只有4s啊?

  考虑数边置换的循环节时不那么暴力。显然两端点在同一循环内的边和在不同循环内的边是不可能处于同一边的循环的,并且第一种情况只与该循环长度有关,第二种情况只与两循环长度有关,先预处理一下就可以了,当然事实上也能直接推出来。不过这复杂度上并没有优化。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 60
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{int x=0,f=1;char c=getchar();while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;
}
int n,c,P,a[N],b[N],fac[N],inv[N],id[N][N],nxt[N*N],f[N],g[N][N],ans,T;
bool flag[N*N];
int ksm(int a,int k)
{int s=1;for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;return s;
}
int C(int n,int m){return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;}
int calc(int m)
{int s=1,tot=n;for (int i=1;i<=m;i++){int t=i;while (t<m&&a[t+1]==a[i]) t++;s=1ll*s*inv[t-i+1]%P;for (int j=i;j<=t;j++)s=1ll*s*C(tot,a[j])%P*fac[a[j]-1]%P,tot-=a[j];i=t;}tot=0;for (int i=1;i<=m;i++) tot=(tot+f[a[i]])%P;for (int i=1;i<=m;i++)for (int j=i+1;j<=m;j++)tot=(tot+g[a[i]][a[j]])%P;return 1ll*s*ksm(c,tot)%P;
}
void dfs(int k,int n,int last)
{if (n==0) ans=(ans+calc(k-1))%P;if (n<last) return;for (int i=last;i<=n;i++)a[k]=i,dfs(k+1,n-i,i);
}
int cycle()
{int tot=0;memset(flag,0,T+1);for (int i=1;i<=T;i++)if (!flag[i]){int x=nxt[i];flag[i]=1;tot++;while (x!=i) flag[x]=1,x=nxt[x];}return tot;
}
int main()
{
#ifndef ONLINE_JUDGEfreopen("bzoj1815.in","r",stdin);freopen("bzoj1815.out","w",stdout);const char LL[]="%I64d\n";
#elseconst char LL[]="%lld\n";
#endifn=read(),c=read(),P=read();fac[0]=1;for (int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%P;inv[0]=inv[1]=1;for (int i=2;i<=n;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P;for (int i=2;i<=n;i++) inv[i]=1ll*inv[i-1]*inv[i]%P;for (int i=1;i<=n;i++){T=0;for (int x=1;x<=i;x++)for (int y=x+1;y<=i;y++)id[x][y]=id[y][x]=++T;for (int x=1;x<=i;x++)for (int y=x+1;y<=i;y++) nxt[id[x][y]]=id[x%i+1][y%i+1];f[i]=cycle();}for (int i=1;i<=n;i++)for (int j=i;j<=n;j++){T=0;for (int x=1;x<=i;x++)for (int y=1;y<=j;y++)id[x][y]=++T;for (int x=1;x<=i;x++)for (int y=1;y<=j;y++)nxt[id[x][y]]=id[x%i+1][y%j+1];g[i][j]=g[j][i]=cycle();}dfs(1,n,1);cout<<1ll*ans*inv[n]%P;return 0;
}

转载于:https://www.cnblogs.com/Gloid/p/10164836.html

BZOJ1815 SHOI2006有色图(Polya定理)相关推荐

  1. (每日一题)P4128 [SHOI2006] 有色图(文末有色图!)(Polya定理)(超级详细,清晰易懂)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 每日一题(莫反 / 多项式 / 母函数 / 群论) 2021.4.13 群论 嘿嘿嘿,本题题名为 有涩 ...

  2. [BZOJ1815BZOJ1488]有色图/图的同构(Polya定理)

    由于有很多本质相同的重复置换,我们先枚举各种长度的点循环分别有多少个,这个暴搜的复杂度不大,n=53时也只有3e5左右.对于每种搜索方案可以轻易求出它所代表的置换具体有多少个. 但我们搜索的是点置换组 ...

  3. [SHOI2006]有色图

    [SHOI2006]有色图 感觉polya定理还没搞太清,写点东西助于理解. 首先注意到这题求的是本质不同的染色方案,这个好像很符合polya定理求的东西. \[l=\frac{1}{|G|}\sum ...

  4. 置换群和Burnside引理,Polya定理

    定义简化版: 置换,就是一个1~n的排列,是一个1~n排列对1~n的映射 置换群,所有的置换的集合. 经常会遇到求本质不同的构造,如旋转不同构,翻转交换不同构等. 不动点:一个置换中,置换后和置换前没 ...

  5. poj2154Color polya定理+欧拉函数优化

    没想到贱贱的数据居然是错的..搞得我调了一中午+晚上一小时(哦不d飞LJH掉RP毕竟他是BUFF)结果重判就对了五次.. 回归正题,这题傻子都看得出是polya定理(如果你不是傻子就看这里),还没有翻 ...

  6. [luogu4128][shoi2006]有色图

    前言 计数题 题目相关 题目链接 题目大意 nnn个点的完全图,对边染色(颜色有mmm种),求本质不同的染色方案数,答案对ppp取模 数据范围 1≤n≤53,1≤m≤1000,1≤p≤1091\le ...

  7. Burnside引理和Polya定理学习笔记

    前言 求·······的方案数 循环同构算一种 一脸懵逼 (于是我觉得系统的学一遍Burnside引理和Polya定理) 正文 置换 置换的概念 对于一个排列aia_iai​ 我们想成iii输进去会出 ...

  8. POJ 2409 Let it Bead (Polya定理)

    题意 用k种颜色对n个珠子构成的环上色,旋转翻转后相同的只算一种,求不等价的着色方案数. 思路 Polya定理 X是对象集合{1, 2, --, n}, 设G是X上的置换群,用M种颜色染N种对象,则不 ...

  9. poj2154 Color ——Polya定理

    题目:http://poj.org/problem?id=2154 今天学了个高端的东西,Polya定理... 此题就是模板,然而还是写了好久好久... 具体看这个博客吧:https://blog.c ...

  10. 【SDOI2013】项链【莫比乌斯反演】【Polya定理】【递推式求通项】【数论】

    题意:TTT 组数据,每组给定 n,an,an,a,求满足下列条件的项链数量: 有 nnn 个珠子. 每个珠子上有三个 [1,a]∩Z[1,a]\cap \Z[1,a]∩Z 的数,且三个数 gcd⁡\ ...

最新文章

  1. Cordova for iOS[ PhoneGap]
  2. OS / 5 种 IO 模型
  3. php热门标签,PHP显示最流行的标签
  4. Flex 学习随笔 ---- 玩 Chart
  5. 数据结构——图-有向带权图的邻接表
  6. java并发临界资源管理
  7. 总结:Linux磁盘分区管理
  8. java http请求 工具类_java模拟http请求调用远程接口工具类
  9. [Flink] Flink运行报错The number of requested virtual cores for application master
  10. 分享一种固定页教在页面底部的方法
  11. 【转】crc16几种标准校验算法及c语言代码
  12. Android ndk下载和环境配置
  13. Web 全栈工程师的自我修养
  14. 章节十:Selenium
  15. android sync 文件夹,如何使用FolderSync在安卓手机上同步文件夹到坚果云?
  16. p图软件pⅰc_pic修图软件下载-pic修图 安卓版v16.4.52-PC6安卓网
  17. 乾隆的太医留下来的民间偏方
  18. 我真的不懂微信营销(一)
  19. win7计算机里不显示摄像头,win7系统不显示摄像头的解决方法
  20. 【数据结构与算法】五、哈希表和链表

热门文章

  1. 什么是java中的监听器_java中什么是监听器
  2. appium java动态等待_appium封装显示等待Wait类和ExpectedCondition接口
  3. 机器学习---分类、回归、聚类、降维的区别
  4. Caffe学习:使用pycaffe绘制网络结构
  5. 在Python中使用XGBoost和scikit-learn进行随机梯度增强
  6. linux安装oracle11g视频,Linux安装oracle11g详细步骤及问题汇总
  7. 后现代婚礼机器人显神通_机器人+无人机 江西新余智能消防显“神通”
  8. 计算机七年级下册课件ppt课件ppt,七年级音乐下册
  9. python excel 教程推荐_python脚本实现数据导出excel格式的简单方法(推荐)
  10. java IDEA 手动替换更新jar包