牛客练习赛69 F.解方程(贝尔级数+线性筛)
传送门:https://ac.nowcoder.com/acm/contest/7329/F
题目大意:
题解:不难发现,
f
(
n
)
f(n)
f(n) 一定为积性函数,这是因为
σ
p
(
n
)
\sigma_p(n)
σp(n) 和
σ
q
(
n
)
\sigma_q(n)
σq(n) 均为积性函数,此时便可以使用贝尔级数展开求出
f
(
n
)
f(n)
f(n) 的表达式。考虑
σ
k
=
id
k
∗
1
\sigma_k=\operatorname{id}_k*1
σk=idk∗1 ,则
σ
k
(
n
)
\sigma_k(n)
σk(n) 的贝尔级数形式就是
σ
k
p
=
id
k
p
×
1
p
=
1
(
1
−
x
)
(
1
−
p
k
x
)
{\sigma_k}_p={\operatorname{id}_k}_p\times 1_p=\frac{1}{(1-x)(1-p^kx)}
σkp=idkp×1p=(1−x)(1−pkx)1 。为了避免记号混淆,令题目中的
p
,
q
p,q
p,q 改为
a
,
b
a,b
a,b 。那么:
f p × σ a p = σ b p f p × 1 ( 1 − x ) ( 1 − p a x ) = 1 ( 1 − x ) ( 1 − p b x ) f p = 1 − p a x 1 − p b x f p = ( id a μ ) p × id b p f ( n ) = ( id a μ ∗ id b ) ( n ) f_p\times {\sigma_a}_p={\sigma_b}_p \\f_p\times \frac{1}{(1-x)(1-p^ax)}=\frac{1}{(1-x)(1-p^bx)} \\f_p=\frac{1-p^ax}{1-p^bx} \\f_p=(\operatorname{id}_a\mu)_p\times {\operatorname{id}_b}_p \\f(n)=(\operatorname{id}_a\mu*\operatorname{id}_b)(n) fp×σap=σbpfp×(1−x)(1−pax)1=(1−x)(1−pbx)1fp=1−pbx1−paxfp=(idaμ)p×idbpf(n)=(idaμ∗idb)(n)
计算 f ( n ) f(n) f(n) 在质数或质数次方数处的取值,得到 f ( p r ) = p r b − p ( r − 1 ) b + a ( r ≥ 1 ) f(p^r)=p^{rb}-p^{(r-1)b+a}\space (r\geq 1) f(pr)=prb−p(r−1)b+a (r≥1) ,不难发现,对于每一个 f ( p k ) ( k > 1 ) f(p^k)\space (k>1) f(pk) (k>1) ,都有 f ( p k ) = p b f ( p k − 1 ) f(p^k)=p^bf(p^{k-1}) f(pk)=pbf(pk−1) ,此时用线性筛维护即可。时间复杂度 O ( n ) O(n) O(n) 。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e7+5,M=998244353;
int cnt=0,prime[N],f[N],bmi[N];
bitset<N> vis;
ll qpow(ll a,ll b){
ll res=1;
while(b){
if(b&1) res=(res*a)%M;
a=(a*a)%M;
b>>=1;
}
return res;
}
void init(ll n,ll a,ll b){
bmi[1]=f[1]=1;
for(int i=2;i<=n;++i){
if(!vis[i]){
prime[cnt++]=i;
bmi[i]=qpow(i,b);
f[i]=((ll)bmi[i]-(ll)qpow(i,a))%M;
}
for(int j=0;i*prime[j]<=n;++j){
int t=i*prime[j];
vis[t]=1;
if(i%prime[j]){
f[t]=((ll)f[i]*(ll)f[prime[j]])%M;
}
else{
f[t]=((ll)f[i]*(ll)bmi[prime[j]])%M;
break;
}
}
}
}
int main(){
ll n,a,b;
cin>>n>>a>>b;
init(n,a,b);
ll res=1;
for(int i=2;i<=n;++i){
ll t=f[i];
if(t<0) t+=M;
res^=t;
}
cout<<res<<endl;
}