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

原文地址:https://www.cnblogs.com/Jackpei/p/12087985.html