定义F(n)为n中不同的质因子个数,求: ∑ni=12F(i),n≤1012 ∑ i = 1 n 2 F ( i ) , n ≤ 10 12
首先考虑一个
O(n23)
O
(
n
2
3
)
的暴力,即
2F(i)
2
F
(
i
)
是在枚举i的质因子集合的子集。那么改成枚举这个子集k,那么有恰好
⌊nk⌋
⌊
n
k
⌋
个数字包含这个集合,也就是:
然后莫比乌斯函数平方的前缀和怎么求呢?继续考虑其意义,然后容斥,则:
然后预处理一波就可以做到 O(n23) O ( n 2 3 ) ;
然后考虑用更数论的办法推:
S(n)=∑ni=1⌊ni⌋ S ( n ) = ∑ i = 1 n ⌊ n i ⌋ 可以直接数论分 O(n−−√) O ( n ) 块求。
复杂度为:
O(∑n√i=1ni2−−√)=O(n−−√∑n√i=11i)=O(n−−√lgn) O ( ∑ i = 1 n n i 2 ) = O ( n ∑ i = 1 n 1 i ) = O ( n l g n ) 。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<assert.h>
#define SN 1000010
#define lint long long
#define mod 1000000007
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
int p[SN],mu[SN],notp[SN];
inline int prelude(int n)
{
mu[1]=1;
for(int i=2,c=0;i<=n;i++)
{
if(!notp[i]) p[++c]=i,mu[i]=-1;
for(int j=1;j<=c&&p[j]<=n/i;j++)
{
int x=p[j]*i;notp[x]=1;
if(i%p[j]) mu[x]=-mu[i];
else { mu[x]=0;break; }
}
}
return 0;
}
inline lint F(lint n,lint ans=0)
{
for(lint s=1,t;s<=n;s=t+1) t=n/(n/s),ans+=(n/s)*(t-s+1);
return ans%mod;
}
int main()
{
lint n,ans=0,sn=1;scanf("%lld",&n);
while((sn+1ll)*(sn+1)<=n) sn++;prelude(sn);
for(int i=1;i<=n/i;i++) if(mu[i]) ans+=mu[i]*F(n/i/i);
return !printf("%lld\n",ans=(ans%mod+mod)%mod);
}