给你一个n 让你计算 F(n)=∑ni=1∑ij=1⌈ij⌉[gcd(i,j)==1]
考虑 g(i)=∑ij=1⌈ij⌉,h(i)=∑ij=1⌈ij⌉[gcd(i,j)==1],f(n)=∑ni=1h(i)
显然有:
g(i)=∑d|ih(id)
由反演可得:
h(i)=∑d|iu(d)g(id)
所以如果我们得到了g(i) ,很容易就可以求出h(i),处理前缀和就得到f(i)。
所以问题就是如何求g(i),
所以这里采取枚举j的做法,
有g[j]=1,g[j+1,j∗2]=2,g[j∗2+1,j∗3]=3,…,g[j∗k+1,n]=k+1
转化一下,就是
g[j,n]+=1,g[j+1,n]+=1,g[j∗2+1,n]+=1,…,g[j∗k+1,n]+=1
所以在每个+1开始的位置加上1,然后前缀和处理一下就行了
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
const int MOD = 1e9+7;
typedef long long ll;
int n;
ll g[N],f[N];
int mu[N],prime[N],vis[N],cnt;
void Init()
{
memset(vis,0,sizeof(vis));
mu[1] = 1;
cnt = 0;
for(int i=2; i<N; i++)
{
if(!vis[i])
{
prime[cnt++] = i;
mu[i] = -1;
}
for(int j=0; j<cnt&&i*prime[j]<N; j++)
{
vis[i*prime[j]] = 1;
if(i%prime[j]) mu[i*prime[j]] = -mu[i];
else
{
mu[i*prime[j]] = 0;
break;
}
}
}
}
int main(){
Init();
for(int i=1;i<N;i++){
g[i]++;
for(int j=i;j<N;j+=i) g[j+1]++;
}
for(int i=1;i<N;i++) g[i]+=g[i-1];
for(int i=1;i<N;i++)
for(int j=i;j<N;j+=i)
f[j]=(f[j]+mu[i]*g[j/i])%MOD;
for(int i=1;i<N;i++) f[i]=(f[i]+f[i-1])%MOD;
while(~scanf("%d",&n)) printf("%lld\n",f[n]);
return 0;
}