题目大意
令 S n = ∑ d ∣ n μ ( n d ) ln ( d ) S_n=\sum\limits_{d\mid n}\mu(\frac nd)\ln(d) Sn=d∣n∑μ(dn)ln(d)
求 e S n m o d 998244353 e^{S_n}\bmod 998244353 eSnmod998244353
题解
变换式子
e
S
n
=
e
∑
d
∣
n
μ
(
n
d
)
ln
(
d
)
=
∏
d
∣
n
d
μ
(
n
d
)
=
∏
d
∣
n
(
n
d
)
μ
(
d
)
\begin{aligned} e^{S_n}&=e^{\sum\limits_{d\mid n}\mu(\frac nd)\ln(d)}\\ &=\prod\limits_{d\mid n}d^{\mu(\frac nd)}\\ &=\prod\limits_{d\mid n}(\frac nd)^{\mu(d)} \end{aligned}
eSn=ed∣n∑μ(dn)ln(d)=d∣n∏dμ(dn)=d∣n∏(dn)μ(d)
对 μ ( d ) \mu(d) μ(d) 的值进行研究
- μ ( d ) = 0 \mu(d)=0 μ(d)=0,这时 ( n d ) μ ( d ) = 1 (\frac nd)^{\mu(d)}=1 (dn)μ(d)=1,对答案没有影响。
- μ ( d ) = 1 \mu(d)=1 μ(d)=1,,这时 ( n d ) μ ( d ) = n d (\frac nd)^{\mu(d)}=\frac nd (dn)μ(d)=dn。
- μ ( d ) = − 1 \mu(d)=-1 μ(d)=−1,,这时 ( n d ) μ ( d ) = d n (\frac nd)^{\mu(d)}=\frac dn (dn)μ(d)=nd。
只有当 d = p 1 p 2 … p m d=p_1p_2\dots p_{m} d=p1p2…pm,或者 d = 1 d=1 d=1, μ ( d ) \mu(d) μ(d) 才不等于 0 0 0,进一步说, μ ( d ) = ( − 1 ) m \mu(d)=(-1)^m μ(d)=(−1)m。
对 n n n 分解质因数得 n = p 1 c 1 p 2 c 2 … p m c m n=p_1^{c_1}p_2^{c_2}\dots p_{m}^{c_m} n=p1c1p2c2…pmcm,记 A = p 1 p 2 … p m A=p_1p_2\dots p_m A=p1p2…pm
于是枚举 d d d 变成了任意枚举 A A A 中的质数。使用 Pollard rho \text{Pollard rho} Pollard rho 算法可在 O ( n 4 ) O(\sqrt[4]{n}) O(4n) 的时间可以分解 n n n,任意枚举 A A A 的质数的时间复杂度为 O ( 2 ω ( n ) ) O(2^{\omega(n)}) O(2ω(n)),单次时间复杂度是 O ( n 4 + 2 ω ( n ) ) O(\sqrt[4]{n}+2^{\omega(n)}) O(4n+2ω(n)),可以通过???赛时我一开始思路是这样,但是打挂了。赛后发现当有一个 p = 998244353 p=998244353 p=998244353 时,逆元求不了。后面 tanjunming2020 给我新思路。下面介绍这个新思路。
继续推上面的的式子
∏ d ∣ n ( n d ) μ ( d ) = n ∑ d ∣ n μ ( d ) ∏ d ∣ n d μ ( d ) = 1 ∏ d ∣ n d μ ( d ) = 1 ∏ d ∣ A d μ ( d ) \begin{aligned} \prod\limits_{d\mid n}(\frac nd)^{\mu(d)}&=\dfrac{n^{\sum\limits_{d\mid n}\mu(d)}}{\prod\limits_{d\mid n}d^{\mu(d)}}\\ &=\dfrac{1}{\prod\limits_{d\mid n}d^{\mu(d)}}\\ &=\dfrac{1}{\prod\limits_{d\mid A}d^{\mu(d)}}\\ \end{aligned} d∣n∏(dn)μ(d)=d∣n∏dμ(d)nd∣n∑μ(d)=d∣n∏dμ(d)1=d∣A∏dμ(d)1
观察 A A A 中的一个质数 p p p 对分母产生的贡献,固定选 p p p,枚举再选 i i i 个质数,然后在剩下的 m − 1 m-1 m−1 个质数中选 i i i 个,莫比乌斯函数值为 ( − 1 ) i + 1 (-1)^{i+1} (−1)i+1。所以分母为 ∏ p ∣ A p ∑ i = 0 m − 1 C m − 1 i ( − 1 ) i + 1 \prod\limits_{p\mid A}p^{\sum\limits_{i=0}^{m-1}C_{m-1}^i(-1)^{i+1}} p∣A∏pi=0∑m−1Cm−1i(−1)i+1
答案为 ∏ p ∣ A p ∑ i = 0 m − 1 C m − 1 i ( − 1 ) i \prod\limits_{p\mid A}p^{\sum\limits_{i=0}^{m-1}C_{m-1}^i(-1)^i} p∣A∏pi=0∑m−1Cm−1i(−1)i。(消掉了一个 − 1 -1 −1 次方)
对组合数进行探究。分类讨论
- 当 m = 1 m=1 m=1,答案为 p p p
- 当 m m m 为偶数且大于 0 0 0,显然, C m − 1 i C_{m-1}^i Cm−1i 和 C m − 1 m − 1 − i C_{m-1}^{m-1-i} Cm−1m−1−i,符号不同,大小相同,会全部消掉。答案为 0 0 0。
- 当
m
m
m 为奇数且大于
1
1
1,由于
C
n
m
=
C
n
−
1
m
+
C
n
−
1
m
−
1
C_n^m=C_{n-1}^m+C_{n-1}^{m-1}
Cnm=Cn−1m+Cn−1m−1,则
∑ i = 0 m − 1 C m − 1 i ( − 1 ) i = 2 + ∑ i = 1 m − 2 C m − 1 i ( − 1 ) i = 2 + ∑ i = 1 m − 2 C m − 2 i ( − 1 ) i + ∑ i = 1 m − 2 C m − 2 i − 1 ( − 1 ) i = 1 + ∑ i = 0 m − 2 C m − 2 i ( − 1 ) i + ∑ i = 0 m − 3 C m − 2 i ( − 1 ) i + 1 = ∑ i = 0 m − 2 C m − 2 i ( − 1 ) i + ∑ i = 0 m − 2 C m − 2 i ( − 1 ) i + 1 = 0 \begin{aligned} \sum\limits_{i=0}^{m-1}C_{m-1}^i(-1)^i&=2+\sum\limits_{i=1}^{m-2}C_{m-1}^i(-1)^i\\ &=2+\sum\limits_{i=1}^{m-2}C_{m-2}^i(-1)^i+\sum\limits_{i=1}^{m-2}C_{m-2}^{i-1}(-1)^i\\ &=1+\sum\limits_{i=0}^{m-2}C_{m-2}^i(-1)^i+\sum\limits_{i=0}^{m-3}C_{m-2}^{i}(-1)^{i+1}\\ &=\sum\limits_{i=0}^{m-2}C_{m-2}^i(-1)^i+\sum\limits_{i=0}^{m-2}C_{m-2}^{i}(-1)^{i+1}\\ &=0\\ \end{aligned} i=0∑m−1Cm−1i(−1)i=2+i=1∑m−2Cm−1i(−1)i=2+i=1∑m−2Cm−2i(−1)i+i=1∑m−2Cm−2i−1(−1)i=1+i=0∑m−2Cm−2i(−1)i+i=0∑m−3Cm−2i(−1)i+1=i=0∑m−2Cm−2i(−1)i+i=0∑m−2Cm−2i(−1)i+1=0
全部情况考虑,得到结论:若 n = p k n=p^k n=pk,则答案为 p p p,否则答案为 1 1 1。
这样,使用 Pollard rho \text{Pollard rho} Pollard rho 得到 n n n 最大的质因数,看它是否完全构成 n n n。
代码如下
#pragma GCC optimize(3)
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 Int;
ll ksc(ll a,ll b,ll c)
{
ll ans=0;
while(b){
if(b&1)
ans=(ans+a)%c;
a=(a+a)%c;
b>>=1;
}
return ans;
}
ll ksm(ll a,ll b,ll c)
{
ll ans=1;
while(b){
if(b&1)
ans=(Int)ans*a%c;
a=(Int)a*a%c;
b>>=1;
}
return ans;
}
ll test[12]={2,3,5,7,11,13,17,19,23,29,31,37},maxn;
bool check(ll a,ll n)
{
ll d=n-1,get=ksm(a,d,n);
if(get!=1) return 1;
while((d&1)^1)
if(d>>=1,(get=ksm(a,d,n))==n-1) return 0;
else if(get!=1) return 1;
return 0;
}
bool miller_rabbin(ll n)
{
if(n<40){
for(int i=0;i<12;i++) if(test[i]==n) return 1;
return 0;
}
for(int i=0;i<12;i++) if(check(test[i],n)) return 0;
return 1;
}
ll gcd(ll a,ll b)
{
return !b?a:gcd(b,a%b);
}
inline ll f(ll x,ll c,ll n)
{
return ((Int)x*x+c)%n;
}
ll pollard_rho(ll x)
{
ll s=0,t=0,c=1ll*rand()%(x-1)+1,val=1;
for(int i=1;;i<<=1,s=t,val=1){
for(int j=1;j<=i;j++){
t=f(t,c,x);
val=(Int)val*abs(t-s)%x;
if(!(j%127)){
ll d=gcd(val,x);
if(d>1) return d;
}
}
ll d=gcd(val,x);
if(d>1) return d;
}
}
vector<ll> aa,bb;
const ll mod=998244353;
ll Ans,invn,n;
void fac(ll x)
{
if(x<=maxn||x<2) return;
if(miller_rabbin(x)){
maxn=max(maxn,x);
return;
}
ll p=x;
while(p>=x) p=pollard_rho(x);
while(x%p==0) x/=p;
fac(x),fac(p);
}
void dfs(int k,ll x,int num,ll y)
{
if(k>=aa.size()){
if(num&1) Ans=Ans*x%mod*invn%mod;
else Ans=Ans*(n%mod)%mod*y%mod;
return;
}
dfs(k+1,x,num,y);
dfs(k+1,x*aa[k]%mod,num+1,y*bb[k]%mod);
}
int main()
{
srand((unsigned)time(NULL));
ll t;
scanf("%lld",&t);
while(t--){
maxn=0;
scanf("%lld",&n);
if(n==1){printf("1 ");continue;}
fac(n);
while(n%maxn==0) n/=maxn;
if(n==1) printf("%lld ",maxn%mod);
else printf("1 ");
}
}