题目大意
最近, Stump \text{Stump} Stump 推导出了 ∑ k = 1 n μ 2 ( k ) = ∑ k = 1 μ ( k ) ⌊ n k 2 ⌋ \sum_{k=1}^n\mu^2(k)=\sum_{k=1}\mu(k)⌊\frac{n}{k^2}⌋ ∑k=1nμ2(k)=∑k=1μ(k)⌊k2n⌋,这震惊了 Yoshinow2001 \text{Yoshinow2001} Yoshinow2001 一整年。
上面的 μ \mu μ 是莫比乌斯函数:如果 n n n 包含平方因子(即有正整数 a > 1 a>1 a>1 使 a 2 ∣ n a^2|n a2∣n),那么 μ ( n ) = 0 \mu(n)=0 μ(n)=0。否则,不妨分解质因数 n = p 1 p 2 ⋯ p k n=p_1p_2\cdots p_k n=p1p2⋯pk,然后 μ ( n ) = ( − 1 ) k \mu(n)=(-1)^k μ(n)=(−1)k。例如: μ ( 1 ) = 1. μ ( 2 ) = μ ( 3 ) = − 1 \mu(1)=1.\mu(2)=\mu(3)=-1 μ(1)=1.μ(2)=μ(3)=−1。
回想一下 ln ( n ) \ln(n) ln(n) 表示以 e e e 为底的 n n n 的对数,其中 e = ∑ i = 1 ∞ 1 i ! ≈ 2.71828 e=\sum_{i=1}^\infty\frac{1}{i!}\approx 2.71828 e=∑i=1∞i!1≈2.71828。
现在 Yoshinow2001 \text{Yoshinow2001} Yoshinow2001 非常愤怒,提出了一个问题!
让:
S ( n ) = ∑ d ∣ n μ ( n d ) ln ( d ) S(n)=\sum_{d|n}\mu(\dfrac{n}{d})\ln(d) S(n)=d∣n∑μ(dn)ln(d)
你需要计算:
e S ( n ) m o d 998244353 e^{S(n)} \mod 998244353 eS(n)mod998244353
当 Stump \text{Stump} Stump 看到题目时,他气坏了!他没有推出 O ( 1 ) O(1) O(1) 的判断规律。
现在你要告诉他什么叫做大佬,写出一个程序在 5 s 5s 5s 内爆切这个问题吧!
思路
我们先把 S ( n ) S(n) S(n) 代入进去,我们要求的式子变为如下形式:
e ∑ d ∣ n μ ( n d ) ln ( d ) e^{\sum_{d|n}\mu(\dfrac{n}{d})\ln(d)} e∑d∣nμ(dn)ln(d)
我们知道 e l n ( n ) = n e^{ln(n)}=n eln(n)=n,则我们可以将式子化为如下形式:
∏ d ∣ n ( n d ) μ ( d ) = ∏ d ∣ n n μ ( d ) ∏ d ∣ n d μ ( d ) \prod_{d|n}(\dfrac{n}{d})^{\mu(d)}=\dfrac{\prod_{d|n} n^{\mu(d)}}{\prod_{d|n} d^{\mu(d)}} d∣n∏(dn)μ(d)=∏d∣ndμ(d)∏d∣nnμ(d)
化为两个式子后我们分别来看,先看上面的式子。
由于底数不变,则式子可以写成如下形式:
n ∑ d ∣ n μ ( d ) n^{\sum_{d|n}\mu(d)} n∑d∣nμ(d)
因为 ∑ d ∣ n μ ( d ) = 0 \sum_{d|n}\mu(d) = 0 ∑d∣nμ(d)=0(莫比乌斯函数的性质),所以这个式子的值就为 1 1 1。
再来看下面的式子。
我们对于 n n n 质因数分解,得 n = p 1 k 1 p 2 k 2 ⋯ p m k m n=p_1^{k_1}p_2^{k_2}\cdots p_m^{k_m} n=p1k1p2k2⋯pmkm。
由于莫比乌斯函数的定义,所以 d d d 不可能包含重复的质因数。
于是我们考虑每个质因数的贡献,可以列出如下式子。
∏ i = 1 m p i ∑ j = 0 k − 1 C k − 1 j ( − 1 ) j − 1 \prod_{i=1}^mp_i^{\sum_{j=0}^{k-1} C_{k-1}^j(-1)^{j-1}} i=1∏mpi∑j=0k−1Ck−1j(−1)j−1
这一步本质上就是将 d d d 质因数分解,由于连乘可以将指数相加,得出以上式子。
则原式变为:
1 ∏ i = 1 m p i ∑ j = 0 k − 1 C k − 1 j ( − 1 ) j − 1 = ∏ i = 1 m p i ∑ j = 0 k − 1 C k − 1 j ( − 1 ) j \dfrac{1}{\prod_{i=1}^mp_i^{\sum_{j=0}^{k-1} C_{k-1}^j(-1)^{j-1}}}=\prod_{i=1}^mp_i^{\sum_{j=0}^{k-1} C_{k-1}^j(-1)^{j}} ∏i=1mpi∑j=0k−1Ck−1j(−1)j−11=i=1∏mpi∑j=0k−1Ck−1j(−1)j
我们考虑 ∑ j = 0 k − 1 C k − 1 j ( − 1 ) j \sum_{j=0}^{k-1} C_{k-1}^j(-1)^{j} ∑j=0k−1Ck−1j(−1)j,这个式子只有当 k − 1 > 0 k-1>0 k−1>0,即 k > 1 k>1 k>1 的时候才为 1 1 1,其余时候皆为 0 0 0。
所以只有当 n n n 只有一种质因子时,答案为 n n n 的质因子,否则答案为 1 1 1。
我们可以枚举 n n n 开 k k k 次方后的数,在判断这个数 k k k 次方等不等于 n n n,再用 miller_rabin \text{miller\_rabin} miller_rabin 来判断是否为质数,如果为质数,则输出该质数。
如果找不到满足条件的质数,则输出 1 1 1。
代码
cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int T, bz[1000005], pn;
LL n, m, ans, p[500000];
__int128 Pow(__int128 a, __int128 b, __int128 MOD) {
__int128 s = 1;
while (b) {
if (b & 1)
s = s * a % MOD;
a = a * a % MOD, b = b >> 1;
}
return s;
}
bool miller_rabin(LL x) {
if (x < 2)
return false;
for (int i = 1; i <= pn; i++) {
if (p[i] == x)
return true;
if (x % p[i] == 0)
return false;
if (Pow(p[i], x - 1, x) != 1)
return false;
LL k = x - 1, t;
while (k % 2 == 0) {
k = k / 2, t = Pow(p[i], k, x);
if (t != 1 && t != x - 1)
return false;
if (t == x - 1)
return true;
}
}
return true;
}
int main() {
for (int i = 2; i <= 1000000; i++) {
if (!bz[i])
p[++pn] = i;
for (int j = 2; j * i <= 1000000; j++) bz[j] = 1;
}
scanf("%d", &T);
while (T--) {
scanf("%lld", &n), ans = n;
if (n == 1) {
printf("1 ");
continue;
}
bool flag = false;
for (int i = 1; i <= 64; i++) {//注意精度问题,我们可以将开i次方后的数+1或-1再尝试一下
LL t = pow((long double)n, (long double)1.0 / i);
if (miller_rabin(t) && Pow(t, i, n + 1) == n) {
flag = true, printf("%lld ", t % 998244353);
break;
}
t = pow((long double)n, (long double)1.0 / i) + 1;
if (miller_rabin(t) && Pow(t, i, n + 1) == n) {
flag = true, printf("%lld ", t % 998244353);
break;
}
t = pow((long double)n, (long double)1.0 / i) - 1;
if (miller_rabin(t) && Pow(t, i, n + 1) == n) {
flag = true, printf("%lld ", t % 998244353);
break;
}
}
if (!flag)
printf("1 ");
}
}