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 & ...
随机推荐
- jvm与dvm两种虚拟机的不同
jvm : java虚拟机 sun dvm: dalvik虚拟机 google 区别: 1.基于的架构不同,jvm 基于栈架构,栈是位于内存上的一个空间,执行指令操作,需要 ...
- web常用开发工具
1.WebStorm[推荐] WebStorm 是jetbrains公司旗下一款JavaScript 开发工具.目前已经被广大中国JS开发者誉为"Web前端开发神器"." ...
- Callable接口及Futrue接口详解
Callable接口 有两种创建线程的方法-一种是通过创建Thread类,另一种是通过使用Runnable创建线程.但是,Runnable缺少的一项功能是,当线程终止时(即run()完成时),我们无法 ...
- iis7下的php实现urlrewrite,并隐藏index.php
1 <rewrite> 2 <rules> 3 <rule name="OrgPage" stopProcessing="true" ...
- MySQL-MMM高可用架构
MySQL-MMM高可用架构 目录 MySQL-MMM高可用架构 一.MMM 1. MMM的概述 2. MMM的应用场景 3. MMM的特点 4. 关于MMM高可用架构的说明 5. 用户及授权 二.案 ...
- 浅谈java代理模式
讲解java代理模式 目录 讲解java代理模式 何谓代理模式 静态代理 动态代理 JDK动态代理 CGLIB动态代理 何谓代理模式 代理模式,即Proxy Pattern,23种java常用设计模式 ...
- Solution Set - Stirling 数相关杂题
<好多题的题解> 「洛谷 P5408」第一类斯特林数·行 根据结论 \[x^{\overline{n}}=\sum_i{n\brack i}x^i, \] 我们只需要求出 \( ...
- python控制浏览器上传文件
自动化爬虫方法和库很多,难点大多数在登录.可以大致分为:普通验证码,扫码登录,QQ一键登录,拖动验证,无痕验证,人工识别(比如12306登录) 万能大法可以破解一切以上需求,自动控制浏览器行为 参考文 ...
- Clickhouse - Replication机制
Clickhouse - Replication机制 1. Replication引擎族 Replication仅对于MergeTree引擎族提供支持, 两者是正交的: ReplicatedMerge ...
- Tabluea、Smartbi可视化仪表盘创建流程图分享
你知道Tableau.Smartbi在可视化仪表盘制作步骤上有何差异吗?下面一起来了解吧~ 根据上面的流程图我们可以了解到,不同于Smartbi是在同一界面即可完成的,Tableau是由很多个工作表组 ...