题解 LOJ 6053
【分析】
显然 \(\boldsymbol f\) 为积性函数,且 \(\boldsymbol f(p)=p\oplus 1=\boldsymbol \varphi(p)\cdot 3^{[2\mid p]}\)
令 \(\boldsymbol g(p)=\boldsymbol \varphi(p)\cdot 3^{[2\mid p]}\) 且 \(\boldsymbol f=\boldsymbol g*\boldsymbol h\) ,则:
\(\begin{aligned} \boldsymbol f(p^k)&=\sum_{i=0}^k\boldsymbol h(p^i)\boldsymbol g(p^{k-i}) \\\\ \boldsymbol f(p^k)&=\sum_{i=1}^{k-1}\boldsymbol h(p^i)\boldsymbol g(p^{k-i})+\boldsymbol h(p^k)+\boldsymbol g(p^k) \\\\ \boldsymbol h(p^k)&=\boldsymbol f(p^k)-\boldsymbol g(p^k)-\sum_{i=1}^{k-1}\boldsymbol h(p^i)\boldsymbol g(p^{k-i}) \end{aligned}\)
则 \(p>2\) 时:
\(\begin{aligned} \boldsymbol h(p^k)&=(p\oplus k)-p^{k-1}(p-1)-\sum_{i=1}^{k-1}\boldsymbol h(p^i)\cdot p^{k-i-1}\cdot (p-1) \\\\\boldsymbol h(p^{k-1})&=(p\oplus k-1)-p^{k-2}(p-1)-\sum_{i=1}^{k-2}\boldsymbol h(p^i)\cdot p^{k-i-2}\cdot (p-1) \\\\\boldsymbol h(p^k)-p\boldsymbol h(p^{k-1})&=(p\oplus k)-p(p\oplus k-1)-\boldsymbol h(p^{k-1})\cdot (p-1) \\\\\boldsymbol h(p^k)&=\boldsymbol h(p^{k-1})+(p\oplus k)-p(p\oplus k-1) \end{aligned}\)
而 \(p=2\) 时:
\(\begin{aligned} \boldsymbol h(p^k)&=(p\oplus k)-3p^{k-1}(p-1)-\sum_{i=1}^{k-1}\boldsymbol h(p^i)\cdot 3p^{k-i-1}\cdot (p-1) \\\\\boldsymbol h(p^{k-1})&=(p\oplus k-1)-3p^{k-2}(p-1)-\sum_{i=1}^{k-2}\boldsymbol h(p^i)\cdot 3p^{k-i-2}\cdot (p-1) \\\\\boldsymbol h(p^k)-p\boldsymbol h(p^{k-1})&=(p\oplus k)-p(p\oplus k-1)-\boldsymbol h(p^{k-1})\cdot 3(p-1) \\\\\boldsymbol h(2^k)-2\boldsymbol h(2^{k-1})&=(2\oplus k)-2(2\oplus k-1)-3\boldsymbol h(2^{k-1}) \\\\\boldsymbol h(2^k)&=-\boldsymbol h(2^{k-1})+(2\oplus k)-2(2\oplus k-1) \end{aligned}\)
而由于 \(\boldsymbol \varphi(p)\cdot 3^{[2\mid p]}=\boldsymbol f(p)=\boldsymbol h(p)+\boldsymbol g(p)=\boldsymbol h(p)+\boldsymbol \varphi(p)\cdot 3^{[2\mid p]}\) 得到 \(\boldsymbol h(p)=0\)
从而根据上述式子 \(k>1\) 时,\(\boldsymbol h(p^k)\) 可以由 \(\boldsymbol h(p^{k-1})\) 递推得到
我们定义 Powerful Number 为所有质因子均出现大于 \(1\) 次的数,以集合语言来讲,则是 \(PN=\{n|\forall (p_i\mid n)\to (p_i^2\mid n), p_i\in Prime\}\)
则不难发现,\(\boldsymbol h(n)=0, n\not\in PN\) 且所有 Powerful Number 均可写为 \(a^2b^3(a, b\in Z_+)\) 的形式
而 \(n\) 范围内,Powerful Number 的数量级为 \(\displaystyle \sum_{a=1}^{\sqrt n} \sum_{b=1}^{\sqrt[3] {n\over a^2}}1=\int_1^{\sqrt n}\text da\int_1^{\sqrt[3]{n\over a^2}}\text db=O(\sqrt n)\)
\(\begin{aligned} \sum_{i=1}^n\boldsymbol f(i)&=\sum_{i=1}^n\sum_{d\mid i}\boldsymbol h(d)\cdot \boldsymbol g({i\over d}) \\\\&=\sum_{d=1}^n\boldsymbol h(d)\cdot \sum_{i=1}^{n/d}\boldsymbol g(i) \\\\&=\sum_{d \in PN}\boldsymbol h(d)\cdot G(n/d)&&\text{(}\boldsymbol h\text{ 仅在 }PN\text{ 处有值 }\text{)} \end{aligned}\)
只要预处理 \(\sqrt n\) 范围内的质数,然后跑 dfs 即可在 \(O(\sqrt n)\) 时间内枚举所有 Powerful Number
先问题化为对于 \(G(n)\) 如何求解
\(\begin{aligned} G(n)&=\sum_{i=1}^n3^{[2\mid i]}\boldsymbol \varphi(i) \\\\&=\sum_{i=1}^n \boldsymbol \varphi(i)+2\sum_{i=1}^n[2\mid i]\boldsymbol \varphi(i) \\\\&=\Phi(n)+2\sum_{i=1}^{n/2}\boldsymbol \varphi(2i) \\\\&=\Phi(n)+2S(n/2) \\\\\ \\\\S(n)&=\sum_{i=1}^n \boldsymbol \varphi(2i) \\\\&=\sum_{i=1}^n \boldsymbol \varphi(i)+\sum_{i=1}^n[2\mid i]\boldsymbol (i) \\\\&=\Phi(n)+S(n/2) \\\\&=\Phi(n)+\Phi(n/2)+\Phi(n/4)+\Phi(n/8)+\cdots&&\text{(}迭代\text{)} \\\\\ \\\\G(n)&=\Phi(n)+2[\Phi(n/2)+\Phi(n/4)+\Phi(n/8)+\cdots] \\\\&=2[\Phi(n)+\Phi(n/2)+\Phi(n/4)+\Phi(n/8)+\cdots]-\Phi(n) \end{aligned}\)
而 \(\boldsymbol \varphi*\boldsymbol I=\boldsymbol {id}\) 得:
\(\displaystyle {n(n+1)\over 2}=\sum_{i=1}^n\boldsymbol {id}(i)=\sum_{i=1}^n\sum_{d\mid i}\boldsymbol \varphi({i\over d})=\sum_{d=1}^n\Phi(n/d)\)
变型得到 \(\displaystyle \Phi(n)={n(n+1)\over 2}-\sum_{d=2}^n\Phi(n/d)\) ,可由杜教筛在 \(O(n^{2\over 3})\) 时间内预处理得到
总时间复杂度为杜教筛的预处理时间 \(O(n^{2\over 3})+\) 杜教筛的运行时间 \(O(n^{2\over 3})+\) 迭代 \(G(n)\) 的时间 \(O(\sqrt n\log n)+\) PN 筛的时间 \(O(\sqrt n)\)
总复杂度为 \(O(n^{2\over 3}+\sqrt n\log n)\)
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef double db;
#define fi first
#define se second
const int Lim=5e6, MAXN=Lim+10, P=1e9+7;
int fc[MAXN], prime[MAXN/10], cntprime, sphi[MAXN];
inline void sieve() {
for(int i=2; i<=Lim; ++i) {
if(!fc[i]) {
prime[++cntprime]=i;
fc[i]=i;
sphi[i]=i-1;
}
for(int j=1; j<=cntprime; ++j)
if(prime[j]*i>Lim) break;
else if(prime[j]<fc[i]) {
fc[prime[j]*i]=prime[j];
sphi[ prime[j]*i ]=sphi[ prime[j] ]*sphi[i];
}
else{
fc[prime[j]*i]=prime[j];
sphi[ prime[j]*i ]=prime[j]*sphi[i];
break;
}
}
sphi[1]=1;
for(int i=2; i<=Lim; ++i) {
sphi[i]+=sphi[i-1];
if(sphi[i]>=P) sphi[i]-=P;
}
}
struct Dusieve{
ll n, val[MAXN];
int Sphi[MAXN], G[MAXN];
int sqr, id1[MAXN], id2[MAXN], cntid;
inline int getid(ll val) { return val<=sqr?id1[val]:id2[n/val]; }
inline int query(ll n) { return G[getid(n)]; }
inline void init(ll n_) {
n=n_;
cntid=0;
sqr=sqrt(n)+0.5;
for(ll l=1, r, d; l<=n; l=r+1) {
r=n/(val[++cntid]=d=n/l);
if(d>sqr) id2[n/d]=cntid;
else id1[d]=cntid;
}
}
inline void work() {
for(int i=cntid; i>=1; --i) {
if(val[i]<=Lim) {
Sphi[i]=sphi[ val[i] ];
continue;
}
ll v=val[i];
int &res=Sphi[i];
res=(v%P); res=(ll)res*(res+1)%P*(P+1>>1)%P;
for(ll l=2, r, d; l<=v; l=r+1) {
r=v/(d=v/l);
res-=(r-l+1)*Sphi[getid(d)]%P;
if(res<0) res+=P;
}
}
for(int i=cntid; i>=1; --i) {
int &res=G[i];
ll v=val[i];
while(v) {
res+=Sphi[getid(v)];
if(res>=P) res-=P;
v>>=1;
}
res=(res*2%P-Sphi[i]+P)%P;
}
}
}ds;
inline int ans(ll n, int flr, int hn) {
int res=(ll)hn*ds.query(n)%P;
for(int i=flr+1; i<=cntprime; ++i) {
int p=prime[i], k=1;
ll val=n/p, newhn=0;
if(val<p) break;
while(val>=p) {
val/=p; ++k;
if(p==2) newhn=(-newhn+(k^2)-2*(k-1^2));
else newhn=newhn+(p^k)-(ll)p*(p^k-1);
newhn=((newhn%=P)<0?newhn+P:newhn);
res+=ans(val, i, (ll)hn*newhn%P);
if(res>=P) res-=P;
}
}
return res;
}
ll n;
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
sieve();
cin>>n;
ds.init(n);
ds.work();
cout<<ans(n, 0, 1);
cout.flush();
return 0;
}