BZOJ2820: YY的GCD
莫比乌斯反演
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #include<vector> 6 #include<cmath> 7 #include<queue> 8 #define MAXN 10000000+10 9 #define INF 0x7f7f7f7f 10 #define LINF 0x7f7f7f7f7f7f7f7f 11 #define ll long long 12 #define pb push_back 13 #define ft first 14 #define sc second 15 #define mp make_pair 16 #define pil pair<int,ll> 17 #define pll pair<ll,ll> 18 using namespace std; 19 int f[MAXN],mu[MAXN],b[MAXN]; 20 vector<int> p; 21 void getmu(){ 22 mu[1]=1; 23 for(int i=2;i<MAXN;i++){ 24 if(!b[i]){ 25 p.pb(i); 26 mu[i]=-1; 27 } 28 for(int j=0;j<p.size()&&p[j]*i<MAXN;j++){ 29 b[p[j]*i]=1; 30 if(i%p[j]==0){ 31 mu[p[j]*i]=0; 32 break; 33 } 34 mu[p[j]*i]=-mu[i]; 35 } 36 } 37 for(int i=0;i<p.size();i++){ 38 for(int j=1;j*p[i]<MAXN;j++){ 39 f[j*p[i]]+=mu[j]; 40 } 41 } 42 for(int i=1;i<MAXN;i++){ 43 f[i]+=f[i-1]; 44 } 45 } 46 int n,m; 47 void solve(){ 48 scanf("%d%d",&n,&m); 49 if(n>m)swap(n,m); 50 int lst; 51 ll ans=0LL; 52 for(int i=1;i<=n;i=lst+1){ 53 lst=min(n/(n/i),m/(m/i)); 54 ans+=1LL*(f[lst]-f[i-1])*(n/i)*(m/i); 55 } 56 printf("%lld\n",ans); 57 } 58 int main() 59 { 60 getmu(); 61 int T; 62 scanf("%d",&T); 63 while(T--){ 64 solve(); 65 } 66 return 0; 67 }