您的位置:首页 > 其它

[51Nod 2026] Gcd and Lcm

2017-10-21 21:28 405 查看

Description

设f(x)=∑i|xμ(i)i



∑i=1n∑j=1nf[gcd(i,j)]f[lcm(i,j)]

n≤1e9

Solution

其实可以发现,f是个积性函数。。。

把gcd(i,j),lcm(i,j) 分解质因数,发现它们的质因子的指数分别对应i或者j这一个质因子的指数,并且一定一个对应i,一个对应j

那么可以将其交换过来配成i和j

就是

∑i=1n∑j=1nf(i)f(j)

=(∑i=1nf(i))2

写出来

先不管平方

∑i=1n∑d|iμ(d)d

随便换一下

∑d=1nμ(d)d⌊nd⌋

可以分块处理

考虑求μ(d)d的前缀和,

令S(n)=∑i=1nμ(i)i

事实上这东西可以杜教筛,怎么办呢

显然

∑i=1ni∑d|iμ(d)=1

变换一下

∑d=1n∑d|iμ(d)i=1

等价于∑d=1n∑d|iμ(i/d)i=1

然后可以写成

∑d=1n∑i=1⌊nd⌋μ(i)id=1

然后提出来

∑d=1ndS(⌊nd⌋)=1

那么1−S(n)=∑d=2ndS(⌊nd⌋)

直接杜教筛即可

Code

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define N 10000005
#define mo 1000000007
#define M 1000007
#define LI 10000000
#define LL long long
using namespace std;
LL s
,n,h[M][2];
bool bz
;
int pr
,mu
,l;
int hash(LL k)
{
LL p=k%M;
while(h[p][1]!=0&&h[p][1]!=k) (p+=1)%=mo;
return p;
}
void prp()
{
mu[1]=1,s[1]=1;
fo(i,2,LI)
{
if(!bz[i]) mu[i]=-1,pr[++l]=i;
for(int j=1;j<=l&&pr[j]*i<=LI;j++)
{
bz[i*pr[j]]=1;
if(i%pr[j]==0)
{
mu[i*pr[j]]=0;
break;
}
mu[i*pr[j]]=-mu[i];
}
s[i]+=s[i-1]+mu[i]*i;
}
}
LL get(LL k)
{
if(k<=LI) return s[k];
int p=hash(k);
if(h[p][1]==k) return h[p][0];
h[p][1]=k;
LL s1=0,i=2;
while(i<=k)
{
LL i1=k/(k/i);
(s1+=((i+i1)*(i1-i+1)/2)%mo*get(k/i))%=mo;
i=i1+1;
}
return h[p][0]=1-s1;
}
int main()
{
cin>>n;
prp();
LL d=1,ans=0;
while(d<=n)
{
LL d1=n/(n/d);
(ans+=(get(d1)-get(d-1))*(n/d)%mo)%=mo;
d=d1+1;
}
printf("%lld\n",ans*ans%mo);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: