[51nod2026]Gcd and Lcm

来源:互联网 发布:阿里云跟阿里巴巴关系 编辑:程序博客网 时间:2024/06/13 23:37

Description

已知

f(n)=d|nμ(d)d

i=1nj=1nf(gcd(i,j))f(lcm(i,j))

n<=1e9

Solution

一眼以为f是φ我是不是没救了QwQ
但是这并不妨碍我们发现f是积性函数
然后把lcm(i,j)写成ij/gcd(i,j),易知i/gcd(i,j)与j互质,gcd(i,j)与i/gcd(i,j)互质
所以f(gcd(i,j))f(ij/gcd(i,j))=f(gcd(i,j))f(i/gcd(i,j))f(j)=f(i)f(j)
于是我们只需要求出(ni=1f(i)2)
杜教筛f即可

Code

#include <cstdio>#include <cstring>#include <algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)using namespace std;typedef long long ll;const int Mo=1e9+7;int pwr(int x,int y) {    int z=1;    for(;y;y>>=1,x=(ll)x*x%Mo)        if (y&1) z=(ll)z*x%Mo;    return z;}const int N=5*1e6;int mu[N+5],p[N+5],a[N+5];bool bz[N+5];void prepare() {    mu[1]=1;    fo(i,2,N) {        if (!bz[i]) p[++p[0]]=i,mu[i]=-1;        fo(j,1,p[0]) {            int k=i*p[j];if (k>N) break;            bz[k]=1;if (!(i%p[j])) break;            mu[k]=-mu[i];        }    }    fo(i,1,N) {        a[i]=a[i-1]+i*mu[i]%Mo;        if (a[i]<0) a[i]=a[i]+Mo;        if (a[i]>=Mo) a[i]=a[i]-Mo;    }}int inv2,n,h[N+5];bool vis[N+5];int get_sum(int x) {    return (ll)x*(x+1)%Mo*inv2%Mo;}int get_mu(int x) {    if (x<=N) return a[x];    int t=n/x;if (vis[t]) return h[t];    int ans=1;    for(int l=2,r;l<=x;l=r+1) {        r=x/(x/l);        int sum=(get_sum(r)-get_sum(l-1)+Mo)%Mo;        ans=(ans+Mo-(ll)sum*get_mu(x/l)%Mo)%Mo;    }    vis[t]=1;h[t]=ans;    return ans;}int main() {    inv2=pwr(2,Mo-2);    scanf("%d",&n);    prepare();get_mu(n);    int ans=0;    for(int l=1,r,la=0;l<=n;l=r+1) {        r=n/(n/l);        int x=(r<=N)?a[r]:h[n/l],sum=(x-la+Mo)%Mo;        ans=(ans+(ll)(n/l)*sum%Mo)%Mo;        la=x;    }    printf("%d\n",(ll)ans*ans%Mo);}