【JZOJ6272】【NOIP提高组A】整除 (division)
题目大意
求[1,n]中满足n|xm−x的x的个数,其中n以n=p1p2p3...pc的形式给出。
c≤50,pi≤104,m≤109
解析
这题关键是n的每个质因子都只有一个。
将方程xm−x≡0 (mod n)变为下列方程:
xim−xi≡0 (mod pi) 1≤i≤c
列出同余方程组:
x≡xi (mod pi)
n=p1p2p3...pc,根据中国剩余定理,在[1,n]内x有且仅有一个解,即一组合法的xi唯一对应一个x。
而将x mod pi又能唯一对应一组xi,因此x的解数就是合法xi的组数,即各合法xi的解数相乘。
问题是如何快速求xim−xi≡0 (mod pi)的解数。
众所周知xm是个积性函数,我们只需要求出[1,pi]内每个质数的m次幂,便可以用线性筛求出每个xi的m次幂,然后暴力判断,就能AC了,但是有更快的方法。
利用了这样一个结论:xm−x≡0 (mod p)的解数为gcd(m−1,p−1)+1。
证明是这样的:
p是一个质数,因此p必定有原根g,根据原根的性质,[1,p−1]内每个数都能用gk mod p表示,原方程可变为:
gmk≡gk (mod p)
根据费马小定理:
mk≡k (mod p−1)
变形:
(m−1)k≡0 (mod p−1)
令y=gcd(m−1,p−1),得到:
m−1yk≡0 (mod p−1y)
这时gcd(m−1y,p−1y)=1,所以p−1y|k,k是在[0,p−2]中的,因此k可以取到p−1y的[0,y−1]倍,所以合法的k有y个,对应了合法的x=gk也有y个,但是x=p也是可以的,所以共y+1个合法的x。结论得证。
然后就能以O(∑logpi)的复杂度解决了,快到飞起。
Code
#include <cstdio>
typedef long long ll;
const ll P = 998244353;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
int T, c;
ll p, m, ans;
int main()
{
freopen("division.in", "r", stdin);
freopen("division.out", "w", stdout);
scanf("%*d%d", &T);
while (T--)
{
scanf("%d%lld", &c, &m);
ans = 1;
for (int i = 1; i <= c; i++) scanf("%lld", &p), ans = ans * (gcd(m - 1, p - 1) + 1) % P;
printf("%lld\n", ans);
}
return 0;
}
作者:zjlcnblogs
出处:https://www.cnblogs.com/zjlcnblogs/p/11299900.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
OI
【推荐】2025 HarmonyOS 鸿蒙创新赛正式启动,百万大奖等你挑战
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】开源 Linux 服务器运维管理面板 1Panel V2 版本正式发布
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个 java 空指针异常的解决过程
· 揭开 SQL Server 和 PostgreSQL 填充因子的神秘面纱
· 没有调度器的协程不是好协程,零基础深入浅出 C++20 协程
· 别做抢活的导演:代码中的抽象层次原则
· 从 Redis 客户端超时到 .NET 线程池挑战
· dotnetty 内存泄漏的BUG修复了
· 20250709 - GMX V1 攻击事件: 重入漏洞导致的总体仓位价值操纵
· Apipost 的AI功能真的还不错啊!建议后端开发和测试人员了解
· 面试官:如何实现大模型连续对话?
· MoneyPrinterTurbo – 免费开源的AI短视频生成工具