51nod 1237 最大公约数之和 V3
题意:(sum_{i=1}^n sum_{j=1}^n (i,j) ,nleq 1e10)
题解:惭愧( imes 2)
(=sum_{d=1}^n d sum_{k=1}^{frac{n}{d}} mu(k) (lfloor frac{n}{dk} floor)^2)
(=sum_{T=1}^n sum_{d|T} dmu(frac{n}{d}) (lfloor frac{n}{T} floor)^2)
(=sum_{T=1}^n varphi(T) (lfloor frac{n}{T} floor)^2)
除法分块 + 杜教筛
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#define ll long long
#define R register int
using namespace std;
namespace Luitaryi {
const int N=4700000,M=1000000007;
ll n,m; int cnt,phi[N+10],p[N>>1]; bool vis[N+10];
inline void pre(int n) { phi[1]=1;
for(R i=2;i<=n;++i) {
if(!vis[i]) p[++cnt]=i,phi[i]=i-1;
for(R j=1,k;j<=cnt&&i*p[j]<=n;++j) {
k=i*p[j],vis[k]=true;
if(i%p[j]==0) {
phi[k]=phi[i]*p[j]; break;
} phi[k]=phi[i]*(p[j]-1);
}
} for(R i=1;i<=n;++i) phi[i]=(phi[i]+phi[i-1])%M;
}
int mem[200010],SZ;
inline int calphi(ll x) {
if(x<=m) return phi[x];
R& ret=x>SZ?mem[SZ+n/x]:mem[x];
if(~ret) return ret;
R ans=0,L=x%M;
for(register ll l=2,r;l<=x;l=r+1) {
r=x/(x/l); ans=(ans+1ll*(r-l+1)*calphi(x/l))%M;
} return ret=(1ll*L*(L+1)/2-ans+M)%M;
}
inline void main() {
scanf("%lld",&n),SZ=sqrt(n),m=pow(n,2.0/3),pre(m);
memset(mem,0xff,sizeof mem);
R lst=0,crt,L,ans=0;
for(register ll l=1,r;l<=n;l=r+1) {
r=n/(n/l),L=n/l%M,crt=calphi(r);
ans=(ans+1ll*(crt-lst)*L%M*L)%M;
lst=crt;
} printf("%d
",(ans+M)%M);
}
} signed main() {Luitaryi::main(); return 0;}
2019.12.23