[bzoj2186][Sdoi2008]沙拉公主的困惑
来自FallDream的博客,未经允许,请勿转载,谢谢。
题意:T组数据,每次求[1,n!]里有多少个与m!互质的数。 T<=10000 n,m<=10^7
一开始想着乱容斥啥的 根本不可做...但是实际上没那么复杂。
考虑把[1,n!]按照取余m!的不同分成m!组,发现要么全都互质,要么全都不互质,所以我们只要求[1,m!]里跟m!互质的数就好了,也就是求φ(m!)
那么这样就很简单了,根据欧拉函数的一套理论(#滑稽),我们先筛出质数,然后φ(m!)=m!∗∏i−1i,其中1⩽且i是质数。
答案就是\frac{n!}{m!}\varphi(m!)
实现上还要线性求个逆元,这都很简单啦。
然后考虑R<=m的情况,貌似出题人没有考虑到或者没有写出来,虽然不判断都能过,但是直接这么算是不行的。
发现p在筛的时候会被除掉,所以在算阶乘的时候忽略它,然后在算的时候也不算它的逆元,可能就行了?
貌似好麻烦,懒得实现了。
#include<iostream> #include<cstdio> #define MN 10000000 using namespace std; inline int read() { int x = 0 , f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar();} while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();} return x * f; } int s[MN+5],T,mod,f[MN+5],num=0,inv[MN+5],p[MN+5]; bool b[MN+5]; int main() { T=read();mod=read(); f[1]=1,p[0]=p[1]=inv[0]=inv[1]=1; for(register int i=2;i<=MN;++i) { if(!b[i]) s[++num]=i; for(int j=1;s[j]*i<=MN;++j) { b[s[j]*i]=1; if(i%s[j]==0) break; } } for(register int i=2;i<=MN;++i) p[i]=1LL*p[i-1]*i%mod,inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod; for(register int i=2;i<=MN;++i) f[i]=(b[i]?f[i-1]:(1LL*f[i-1]*(i-1)%mod*inv[i]%mod)); for(register int i=1;i<=T;++i) { int n=read(),m=read(); printf("%d\n",1LL*p[n]*f[m]%mod); } return 0; }
FallDream代表秋之国向您问好!
欢迎您来我的博客www.cnblogs.com/FallDream
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合终身会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· C# 代码如何影响 CPU 缓存速度?
· 智能桌面机器人:使用 .NET 为树莓派开发 Wifi 配网功能
· C# 模式匹配全解:原理、用法与易错点
· 记一次SSD性能瓶颈排查之路——寿命与性能之间的取舍
· 理解 .NET 结构体字段的内存布局
· 【故障公告】6月9日 17:24~17:34 再次遭遇攻击(晚上遭遇更疯狂的攻击)
· 3 个超火的开源项目「GitHub 热点速览」
· C#-Visual Studio工具使用实践
· 上周热点回顾(6.2-6.8)
· [原创]《C#高级GDI+实战:从零开发一个流程图》第01章:有什么用、有什么效果?