洛谷【P2257】 YY的GCD
出处:http://www.cnblogs.com/peng-ym/p/8652288.html ( 直接去出处那看就好了 )
题目描述
- 神犇YY虐完数论后给傻×kAc出了一题
- 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对
kAc这种傻×必然不会了,于是向你来请教…… - 多组输入
#include<bits/stdc++.h> #define LL long long #define ULL unsigned long long #define rep(i,j,k) for(int i=j;i<=k;i++) #define dep(i,j,k) for(int i=k;i>=j;i--) #define INF 0x3f3f3f3f #define mem(i,j) memset(i,j,sizeof(i)) #define make(i,j) make_pair(i,j) #define pb push_back using namespace std; const int N=1e7+5; bool vis[N]; int pre[N],sum[N],mu[N],tot; void init() { mu[1]=1; rep(i,2,10000000) { if(!vis[i]) { pre[++tot]=i; mu[i]=-1 ; } rep(j,1,tot) { if(i*pre[j]>N-5) break; vis[i*pre[j]]=1; if(i%pre[j]==0) break; mu[i*pre[j]]=-mu[i]; } } rep(j,1,tot) { for(int i=1;i*pre[j]<=N-5;i++) { sum[i*pre[j]]+=mu[i]; } } rep(i,1,N-5) sum[i]+=sum[i-1]; } int main() { init(); int t,n,m; 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)); ans+=1LL*(n/l)*(m/l)*(sum[r]-sum[l-1]); } printf("%lld\n",ans); } return 0; }
一步一步,永不停息