LGP6276题解
众所周知,排列是一个置换,一个置换是一车环。
步数就是这些环长的 \(lcm\)。
如果你去思考直接 DP,会发现很困难,根本设不出来状态。于是考虑正难则反:每个质数幂 \(p^k\) 对答案的贡献。
可以发现,如果设 \(f[p^k]\) 是 \(p^k\) 在 \(f[p^k]\) 个排列的 \(lcm\) 中出现过,那么答案是 \(\sum_{p^k\leq n}p^{f[p^k]}\)。
考虑去计算这个 \(f\)。计算出现过似乎也很困难,正难则反计算没出现过的。(后文令 \(t=p^k\))
然后有一个显然的 DP:设 \(dp[n]\) 为 \(n\) 个元素构成的置换群中,没有一个环的长度是 \(t\) 的倍数。那么似乎只需要从非 \(t\) 的倍数转移过来就可以了。
但是我们并不会计算新加入若干个元素会产生多少个新排列。考虑原本有 \(n\) 个元素的情况下加入了一个大小为 \(m\) 的环。
我们强制钦定 \(1\) 必须在这个环中,那么我们还需要从 \([2,n+m]\) 中选出 \([m-1]\) 个数,然后有 \((m-1)!\) 种不同的排列方式。所以方案数乘上了 \(\binom{n+m-1}{m-1}(m-1)!=\frac{(n+m-1)!}{n!}\)。
然后我们好像会了 \(O(n^3)\) 计算这个玩意儿(
考虑优化,正难则反。我们不计算非 \(t\) 倍数位置转移过来的值,考虑维护前面所有位置转移过来的值减去 \(t\) 倍数转移过来的值。这个是很好维护的。
于是做到了 \(O(n^2)\)。
#include<cstdio>
typedef unsigned ui;
typedef __uint128_t LL;
typedef unsigned long long ull;
const ui M=7505;
struct Barrett{
ull m,b;
Barrett(const ui&m=1):m(m),b(((LL(1)<<80)+m-1)/m){}
friend inline ull operator%(const ull&a,const Barrett&mod){
return a-mod.m*(LL(mod.b)*a>>80);
}
}mod,MOD;
ui n,m,tm,TM,c[M],S[M],dp[M],minp[M];
inline ui pow(ui a,ui b){
ui ans(1);for(;b;b>>=1,a=1ull*a*a%mod)if(b&1)ans=1ull*ans*a%mod;return ans;
}
signed main(){
ui ans(1),fac(1);
scanf("%u%u",&n,&m);minp[1]=1;
mod=Barrett(tm=m);MOD=Barrett(TM=m-1);
for(ui i=1;i<=n;++i)c[i]=1,fac=1ull*fac*i%MOD;
for(ui i=2;i<=n;++i)if(!minp[i]){
for(ui j=i*i;j<=n;j+=i)minp[j]=1;
for(ui j=i;j<=n;j*=i)minp[j]=i;
}
for(ui i=2;i<=n;++i){
for(ui j=1;j+i-1<=n;++j)c[j]=1ull*c[j]*(i+j-2)%MOD;
if(minp[i]<=1)continue;
const ui&pk=i;ui sum(1);
dp[0]=1;S[0]=1;
for(ui i=1;i<=n;++i){
if(pk<=i)S[i]=1ull*S[i-pk]*c[i-pk+1]%MOD;else S[i]=0;
dp[i]=(TM+sum-S[i])%MOD;
S[i]=(1ull*S[i]*i+dp[i])%MOD;
sum=(1ull*sum*i+dp[i])%MOD;
}
ans=1ull*ans*pow(minp[i],TM+fac-dp[n])%mod;
}
printf("%u",ans);
}
但是这样真的够快吗?
考虑生成函数。
置换是一个典型的有标号计数问题。只需要计算出一个环的 EGF 再将其 \(\exp\) 即可。
而一个环的 EGF 显然是 \(\sum_{i=1}\frac{(i-1)!}{i!}x^i-\sum_{i=1}\frac{(it-1)!}{(it)!}x^{it}\)。
\]
\]
\]
\]
注意到 \(\frac{1}{1-x}\) 是前缀和,分子又只在 \(t\) 的倍数处有值,所以可以考虑改写一下这个东西:
\]
\]
\]
剩下的就交给广义二项式定理吧。
设 \(m=\lfloor\frac{n}{t}\rfloor\):
\]
\]
\]
但是这个是在指数上做的,所以模数并不是质数。
注意到这个 \(it\) 将 \(n!\) 分成了 \(m+1\) 段,可以将 \(n!\) 看做一个序列,我们只需要支持查询区间乘积即可。
使用猫树可以做到 \(O(n\log n)\) 的复杂度。
#include<cstdio>
typedef unsigned ui;
typedef __uint128_t LL;
typedef unsigned long long ull;
const ui M=7505;
ui n,m,minp[M];
struct Barrett{
ull m,b;
Barrett(const ui&m=1):m(m),b(((LL(1)<<80)+m-1)/m){}
friend inline ull operator%(const ull&a,const Barrett&mod){
return a-mod.m*(LL(mod.b)*a>>80);
}
}mod,MOD;
struct DS{
ui D,len,lg[8192],prod[15][8192];
inline void init(const ui&n){
D=0;len=1;
while((1<<D)<=n)++D,len<<=1;
for(ui i=1;i<=len;++i)prod[0][i]=i;
for(ui i=1;i<=len;++i)lg[i]=lg[i>>1]+1;
for(ui d=1;d<=D;++d){
for(ui k=1;k<=(len>>d);++k){
const ui&L=k-1<<d,&R=k<<d,&mid=L+R>>1;
prod[d][mid]=mid;prod[d][mid+1]=mid+1;
for(ui i=mid-1;i>=L+1;--i)prod[d][i]=1ull*prod[d][i+1]*i%MOD;
for(ui i=mid+1+1;i<=R;++i)prod[d][i]=1ull*prod[d][i-1]*i%MOD;
}
}
}
inline ui operator()(const ui&L,const ui&R){
if(L>R)return 1;if(L==R)return L;
ui d=lg[L-1^R-1];return 1ull*prod[d][L]*prod[d][R]%MOD;
}
}SGT;
inline ui pow(ui a,ui b){
ui ans(1);for(;b;b>>=1,a=1ull*a*a%mod)if(b&1)ans=1ull*ans*a%mod;return ans;
}
inline ui Solve(const ui&k){
const ui&m=n/k;ui ans;ans=SGT(m*k+1,n);
for(ui i=1;i<=m;++i)ans=1ull*ans*SGT((i-1)*k+1,i*k-1)%MOD,ans=1ull*ans*(i*k-1)%MOD;
return ans;
}
signed main(){
ui ans(1),fac(1);
scanf("%u%u",&n,&m);
mod=Barrett(m);MOD=Barrett(m-1);SGT.init(n);
for(ui i=1;i<=n;++i)fac=1ull*fac*i%MOD;
for(ui i=2;i<=n;++i){
if(!minp[i]){
for(ui j=i*i;j<=n;j+=i)minp[j]=1;
for(ui j=i;j<=n;j*=i)minp[j]=i;
}
if(minp[i]>1)ans=1ull*ans*pow(minp[i],m-1+fac-Solve(i))%mod;
}
printf("%u",ans);
}
LGP6276题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
随机推荐
- redhat更改yum源及安装PHP环境
redhat更新yum源 删除同RHEL一同安装的yum源 rpm -qa|grep yum #查看本地yum yum list | wc -l #看个数 yum install pip #看现象 r ...
- PHP中 die,die(),exit,exit(),return,return() 的区别
die:是遇到错误才停止die():停止程序运行,输出内容exit:是停止程序运行,是直接停止,并且不运行后续代码,不输出内容exit():可以显示内容.exit(0):正常运行程序并退出程序:exi ...
- 计算机辅助数据绘图(matlab\python\js)
1. matlab绘图 官方说明:https://ww2.mathworks.cn/help/matlab/creating_plots/types-of-matlab-plots.html 基本图形 ...
- .NET 固定时间窗口算法实现(无锁线程安全)
一.前言 最近有一个生成 APM TraceId 的需求,公司的APM系统的 TraceId 的格式为:APM AgentId+毫秒级时间戳+自增数字,根据此规则生成的 Id 可以保证全局唯一(有 N ...
- 基于zynq XC7Z100 FMC接口通用计算平台
1.板卡概述 此板卡是北京太速研发,由SoC XC7Z100-2FFG900I芯片来完成卡主控及数字信号处理,XC7Z100内部集成了两个ARM Cortex-A9核和一个kintex 7的FPGA, ...
- Haar小波分析
一 尺度函数与小波函数 基本尺度函数定义为:,对其向右平移任意 k 个单位,构成函数族 , 该函数族在 空间中正交,证明如下: 1 : 2 当 m 不等于 k 时, 函数族 构成一组正交基,并形成 ...
- suse 12 二进制部署 Kubernetets 1.19.7 - 第06章 - 部署kube-apiserver组件
文章目录 1.6.部署kube-apiserver 1.6.0.创建kubernetes证书和私钥 1.6.1.生成kubernetes证书和私钥 1.6.2.创建metrics-server证书和私 ...
- Xshell在Windows和Linux间文件的上传和下载
本文通过lrzsz来实现Windows和Linux间文件间的文件传输. lrzsz使用 XMODEM.YMODEM 和 ZMODEM 文件传输协议来实现文件的上传和下载.相比 FTP 或者 WinSC ...
- Vue-从入门到第三次世界大战_1
前言:当然世界大战是大家都不希望看到的这里是代表我会一直更新下去 ,那我为什么要这么写,没错我就是标题党. 先说下Vue介绍: 官网:https://cn.vuejs.org/ 为什么用:因为是TMD ...
- Django整体模型理解(1)
Django大概理解 *models: 设计一个模型,即在数据库中设计一个表,一个模型就是对应一个数据库中的表:models是一个类,类名就是表名,而类的属性就是表的字段.如下例子设计了两个表: f ...