题意:求 中有有多少数是 的互质数
思路
互质数数量——欧拉函数
概念
定义 为欧拉函数 其等于 1~n当中与n互质的数的个数 公式 其中 p 为质数
证明
利用 容斥原理 证明,将公式乘开可以看到: 1. 奇数相减,偶数相加,正是不考虑重叠部分,先减去再加回 2. 首先,每个数都可以拆成质因数p相乘, 意味着1~N中,p的倍数的个数,其余N都有p为约数,所以不是互质数, 就是去掉这些数,由于每个数都是p的相乘(或幂), 可以表示N以内所有可能的数。 3. 容斥原理,先减去再加回可以算出剩余的数,即互质数的个数
Link to original
但是考虑到 的表示虽然可以用快速幂求,但是取模后,其欧拉函数数值会与原来不同
发现 的质因数与 完全一致,只是每个多个幂指数b 即
快速幂求 再求 a的欧拉函数
实现
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int mod = 998244353;
LL ans;
LL a, b;
int main()
{
cin >> a >> b;
//特判1,因为此题a取不到
if(a == 1)
{
cout << 0 << endl;
return 0;
}
LL t = a;
ans = a;
//cout << ans << endl;
for(int i = 2; i <= a / i; i ++)
{
if(a % i == 0)
{
//找到素数
ans = ans / i * (i - 1);
while(a % i == 0)
{
a /= i;
}
}
}
//a大于根号a的那个数刚好是质数
if(a > 1)
ans = ans / a * (a - 1);
//a的质因数就是a^b的质因数
//a^b 的欧拉函数等于 a^b-1 * a的欧拉函数,为什么拆开a,是因为取模后求欧拉函数
//不一定可以整除,数值不一定对
//a的快速幂
LL res = 1;
b = b - 1;
while(b)
{
if(b & 1) res = res * t % mod;
b >>= 1;
t = t * t % mod;
}
//cout << ans << endl;
ans = res * ans % mod;
cout << ans << endl;
return 0;
}
这么简单的数学怎么会不懂呢