题解 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;
}
posted @ 2021-09-30 14:53  JustinRochester  阅读(22)  评论(0编辑  收藏  举报