洛谷P2257 莫比烏斯反演
阿新 • • 發佈:2018-12-11
#include<bits/stdc++.h> using namespace std; const int maxn=1e7+10; typedef long long ll; bool vis[maxn]; int mu[maxn]; ll sum[maxn]; int prime[maxn]; int g[maxn]; void get_mu(int n){ int tot=0; mu[1]=1; for(int i=2;i<=n;i++){ if(!vis[i]){ mu[i]=-1; prime[tot++]=i; } for(int j=0;j<tot&&prime[j]*i<=n;j++){ vis[prime[j]*i]=1; if(i%prime[j]==0){ mu[i*prime[j]]=0; break; }else{ mu[i*prime[j]]=-mu[i]; } } } for(int j=0;j<tot;j++){ for(int i=1;i*prime[j]<=n;i++){ g[i*prime[j]]+=mu[i]; } } for(int i=1;i<=n;i++){ sum[i]+=sum[i-1]+g[i]; } } int main(){ get_mu(10000000); int n,m; int T; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); if(n>m) swap(n,m); ll ans=0; for(int l=1,r;l<=n;l=r+1){ r=min(n/(n/l),m/(m/l)); if(r>n) r=n; ans+=1ll*(n/l)*(m/l)*(sum[r]-sum[l-1]); } printf("%lld\n",ans); } }