洛谷 P6276 - [USACO20OPEN]Exercise P(组合数学+DP)
废了,又不会做/ll
orz czx 写的什么神仙题解,根本看不懂(%%%%%%%%%
首先显然一个排列的贡献为其所有置换环的乘积。考虑如何算之。
碰到很多数的 LCM 之积只有两种可能,一是 Min-Max 容斥将 LCM 转化为 GCD,而是枚举质因子及其次数算贡献。但对于此题而言前者不是太可做(可能有复杂度不错(大概 \(n^2d(n)\)?)的解法,不过我没有细想所以也不太清楚),因此考虑后者。
考虑用类似于差分的思想,对于每个质因子 \(p\) 的每个次数 \(k\),我们考虑计算一下存在一个置换环大小为 \(p^k\) 的排列个数 \(c\),那么我们令答案乘以 \(p^c\),不难发现对于一个排列,如果其置换环大小中 \(p\) 次数最多的一项的次数为 \(k'\),那么它的贡献会在 \(k=1,2,3,\cdots,k'\) 处各被算一次,因此这样计算恰好可以算到所有置换环的贡献。于是限制问题转化为,如何求有多少个排列,满足其至少有一个置换环大小为 \(x=p^k\) 的倍数。
考虑从反面入手,即计算有多少个长度为 \(n\) 的排列不含任何长度为 \(x\) 的置换环,设其为 \(f_n\)。那么这个子问题的答案就是 \(n!-f_n\)。那么如何求 \(f_i\) 呢?我们再从反面入手,计算一下含有长度为 \(x\) 的置换环的排列个数(为什么要一来一回搞两次反面呢?因为直接做递推式中需要用到 \(f_i\)),那么我们枚举长度为 \(x\) 的置换环的长度之和 \(j\),设 \(g_j\) 表示有多少个长度为 \(j\) 的排列满足其每个置换环大小都是 \(x\) 的倍数,那么有 \(f_i=i!·\sum\limits_{j\in[1,i]}\dbinom{i}{j}g_jf_{i-j}\),组合数表示分配 \(j\) 个数给大小是 \(x\) 的倍数的置换环的方案数,一目了然。接下来考虑如何求 \(g_i\),我们枚举 \(1\) 所在的置换环的大小 \(j\),类似地有 \(\sum\limits_{j\in[1,i]}g_{i-j}\dbinom{i-1}{j-1}(j-1)!\)。注意到只有 \(x\mid i\) 时 \(g_i\ne 0\),因此有用的 \(f,g\) 各只有 \(\dfrac{n}{x}\) 个,也就保证了复杂度。这部分可能可以容斥,不过没有细想(
总复杂度 \(\sum\limits_{i=1}^n\dfrac{n^2}{i^2}=\mathcal O(n^2)\),因为 \(\sum\limits_{n>0}\dfrac{1}{n^2}<2\)。
const int MAXN=7500;
int n,mod,phi,c[MAXN+5][MAXN+5],fac[MAXN+5];
int qpow(int x,int e){
int ret=1;
for(;e;e>>=1,x=1ll*x*x%mod) if(e&1) ret=1ll*ret*x%mod;
return ret;
}
int pr[MAXN/5+5],prcnt=0,vis[MAXN+5];
void sieve(int n){
for(int i=2;i<=n;i++){
if(!vis[i]) pr[++prcnt]=i;
for(int j=1;j<=prcnt&&pr[j]*i<=n;j++){
vis[pr[j]*i]=1;if(i%pr[j]==0) break;
}
}
}
int f[MAXN+5],g[MAXN+5];
int calc(int x){
memset(f,0,sizeof(f));memset(g,0,sizeof(g));g[0]=1;
for(int i=x;i<=n;i+=x) for(int j=x;j<=i;j+=x) g[i]=(g[i]+1ll*c[i-1][j-1]*g[i-j]%phi*fac[j-1])%phi;
// for(int i=x;i<=n;i+=x) printf("%d %d\n",i,g[i]);
for(int i=n%x;i<=n;i+=x){
f[i]=fac[i];
for(int j=x;j<=i;j+=x) f[i]=(f[i]-1ll*f[i-j]*g[j]%phi*c[i][j]%phi+phi)%phi;
} return (fac[n]-f[n]+phi)%phi;
}
int main(){
scanf("%d%d",&n,&mod);phi=mod-1;sieve(n);
for(int i=(fac[0]=1);i<=n;i++) fac[i]=1ll*fac[i-1]*i%phi;
for(int i=0;i<=n;i++){
c[i][0]=1;
for(int j=1;j<=i;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%phi;
} int res=1;
// for(int i=1;i<=n;i++) printf("%d\n",calc(i));
for(int i=1;i<=prcnt;i++) for(int j=pr[i];j<=n;j*=pr[i])
res=1ll*res*qpow(pr[i],calc(j))%mod;
printf("%d\n",res);
return 0;
}
洛谷 P6276 - [USACO20OPEN]Exercise P(组合数学+DP)的更多相关文章
- 洛谷P3158 [CQOI2011]放棋子 组合数学+DP
题意:在一个m行n列的棋盘里放一些彩色的棋子,使得每个格子最多放一个棋子,且不同颜色的棋子不能在同一行或者同一列.有多少祌方法? 解法:这道题不会做,太菜了qwq.题解是看洛谷大佬的. 设C是组合数, ...
- 洛谷P2606 [ZJOI2010]排列计数 组合数学+DP
题意:称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很大, ...
- 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)
洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...
- 洛谷 P3177 [HAOI2015]树上染色 树形DP
洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...
- 洛谷 P4072 [SDOI2016]征途 斜率优化DP
洛谷 P4072 [SDOI2016]征途 斜率优化DP 题目描述 \(Pine\) 开始了从 \(S\) 地到 \(T\) 地的征途. 从\(S\)地到\(T\)地的路可以划分成 \(n\) 段,相 ...
- 洛谷P1880 石子合并(区间DP)(环形DP)
To 洛谷.1880 石子合并 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1 ...
- 洛谷P1063 能量项链(区间DP)(环形DP)
To 洛谷.1063 能量项链 题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的 ...
- 洛谷P1282 多米诺骨牌 (DP)
洛谷P1282 多米诺骨牌 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中 ...
- 洛谷 P5469 - [NOI2019] 机器人(区间 dp+拉格朗日插值)
洛谷题面传送门 神仙题,放在 D1T2 可能略难了一点( 首先显然对于 P 型机器人而言,将它放在 \(i\) 之后它会走到左边第一个严格 \(>a_i\) 的位置,对于 Q 型机器人而言,将它 ...
随机推荐
- 【机器学习基础】逻辑回归——LogisticRegression
LR算法作为一种比较经典的分类算法,在实际应用和面试中经常受到青睐,虽然在理论方面不是特别复杂,但LR所牵涉的知识点还是比较多的,同时与概率生成模型.神经网络都有着一定的联系,本节就针对这一算法及其所 ...
- 项目实战:Qt文件改名工具 v1.2.0(支持递归检索,搜索:模糊匹配,前缀匹配,后缀匹配;重命名:模糊替换,前缀追加,后缀追加)
需求 在整理文件和一些其他头文件的时候,需要对其名称进行整理和修改,此工具很早就应该写了,创业后,非常忙,今天抽空写了一个顺便提供给学习. 工具和源码下载地址 本篇文章的应用包和源码包可在 ...
- LeetCode:回溯算法
回溯算法 这部分主要是学习了 labuladong 公众号中对于回溯算法的讲解 刷了些 leetcode 题,在此做一些记录,不然没几天就忘光光了 总结 概述 回溯是 DFS 中的一种技巧.回溯法采用 ...
- BUAA2020软工团队beta得分总表
BUAA2020软工团队beta得分总表 [TOC] 零.团队博客目录及beta阶段各部分博客地址 团队博客 计划与设计博客 测试报告博客 发布声明博客 事后分析博客 敏 杰 开 发♂ https:/ ...
- Beta阶段第八次会议
Beta阶段第八次会议 时间:2020.5.24 完成工作 姓名 工作 难度 完成度 ltx 1.修改一下小程序游客模式的风格 轻 80% xyq 1.针对昨天提出的意见对场地申请表格进行修改 中 9 ...
- [Beta]the Agiles Scrum Meeting 5
会议时间:2020.5.19 20:00 1.每个人的工作 今天已完成的工作 成员 已完成的工作 issue yjy 为评测机增加更多评测指标 评测部分增加更多评测指标 tq 为评测机增加更多评测指标 ...
- Linux C语言链表你学会了吗?
链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用.链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节 ...
- 零基础入门之Linux进程基础
计算机实际上可以做的事情实质上非常简单,比如计算两个数的和,再比如在内存中寻找到某个地址等等.这些最基础的计算机动作被称为指令(instruction).所谓的程序(program),就是这样一系列指 ...
- 用Python去除PDF水印
今天介绍下用 Python 去除 PDF (图片)的水印.思路很简单,代码也很简洁. 首先来考虑 Python 如何去除图片的水印,然后再将思路复用到 PDF 上面. 这张图片是前几天整理<数据 ...
- Python gpu 显卡小工具 gpu
安装 pip install gpustat 或者 换源 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade gpust ...