习题:神犇和蒟蒻(杜教筛)
题目
思路
对于A而言。。。。显然A=1
\[设n=\prod p_i^{a_i}\\\varphi(n)=\prod \varphi(p_i^{a_i})\\\varphi(n^2)=\prod\varphi(p_i^{2a_i})\\考虑到\varphi之中全部都是质数,\\\varphi(p^a)=p^a-p^{a-1}\\\varphi(p^{2a})=p^{2a}-p^{2a-1}=p^a(p^a-p^{a-1})\\\varphi(n^2)=\prod p^a\varphi(p^a)\\\varphi(n^2)=n\varphi(n)
\]
\[设f(i)=\varphi(i^2)=i\varphi(i),F(i)=\sum_{i=1}^{n}f(i)\\设g(i)=i,G(i)=\sum_{i=1}^ng(i)\\那么h(i)=(f*g)(i)=i^2
\]
\[那么根据杜教筛的结论,有\\F(n)=\frac{H(n)-\sum_{d=2}^ng(i)F(\lfloor\frac{n}{d}\rfloor)}{g(1)}
\]
时间复杂度$O(n^{\frac{2}{3}}) $
代码
#include<unordered_map>
#include<iostream>
using namespace std;
const int mod=1e9+7;
const int inv6=166666668;
const int inv2=500000004;
int n;
unordered_map<int,int> mf;
long long f[10000005];
long long summ(int n)
{
return 1ll*n*(n+1)%mod*inv2%mod;
}
long long getphi(int n)
{
if(n<=10000000&&f[n])
return f[n];
if(mf.count(n))
return mf[n];
long long temp=1ll*n*(n+1)%mod*(2*n+1)%mod*inv6%mod;
for(int l=2,r;l<=n;l=r+1)
{
r=min(n/(n/l),n);
temp=(temp-(summ(r)-summ(l-1))*getphi(n/l))%mod;
}
temp=(temp%mod+mod)%mod;
if(n<=10000000)
return f[n]=temp;
else
return mf[n]=temp;
}
int main()
{
cin>>n;
cout<<1<<'\n'<<getphi(n);
return 0;
}

浙公网安备 33010602011771号