原题链接:
https://www.51nod.com/onlineJudge/questionCode.html#problemId=1742¬iceId=324902
answer=∑i=1n∑d|i(1−μ2(i))=∑i=1n∑d|i1−∑i=1n∑d|inμ2(i)=∑d=1n∑i≤n,d|i1−∑d=1n∑i≤n,d|iμ2(i)=∑d=1n⌊nd⌋−∑d=1nμ2(d)⌊nd⌋
对于
∑i=1nμ2(i)
定义: f(k) 为 [1,n] 中,平方因子最大为 k2 的集合。
比如: 32 的因子有: 1,2,4,8,16,32
其中,最大的平方因子是 16 .
那么对于一个数字。他拆成这种表示唯一的。(形如 a2b )
定义:
F(k)=∑k|df(d)=⌊nk2⌋
∑i=1nμ2(i)=f(1)=∑k=1nμ(k)F(k)=∑k=1nμ2(k)⌊nk2⌋
即:
∑k=1⌊n√⌋μ2(k)⌊nk2⌋
分段计算即可。
#include <algorithm>
#include <string.h>
#include <cmath>
#define MAXN 1111111
using namespace std;
typedef long long LL;
const int m=1111;
int mu[MAXN]={0,-1};
int M(int n)
{
int ans=0;
for(int i=1;i*i<=n;i++) ans+=mu[i]*(n/(i*i));
return ans;
}
LL slove(int n)
{
if(n==0)return 0;
LL ans=0;
if(n<MAXN)
for(int i=1;i<=n;i++) ans+=(mu[i])?0:(n/i);
else
{
int bu=M(n);
for(int L=1;L<m;L++)
{
int k=M(n/(L+1));
ans-=(LL)L*(bu-k);
bu=k;
}
for(int i=n/m;i;i--) ans-=(mu[i])?(n/i):0;
int lim=sqrt(n)+1;
for(int L=1;L<lim;L++) ans+=(LL)L*(n/L-n/(L+1));
for(int i=n/lim;i;i--) ans+=n/i;
}
return ans;
}
int main ()
{
for(int i=1;i<MAXN;i++)
{
mu[i]=-mu[i];
for(int j=i<<1;j<MAXN;j+=i) mu[j]+=mu[i];
}
int a,b;
scanf("%d %d",&a,&b);
printf("%lld\n",slove(b)-slove(a-1));
return 0;
}