bzoj 2820 YY的GCD(莫比乌斯反演)
Description
神犇YY虐完数论后给傻×kAc出了一题
给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对
kAc这种傻×必然不会了,于是向你来请教……
多组输入
Input
第一行一个整数T 表述数据组数
接下来T行,每行两个正整数,表示N, M
Output
T行,每行一个整数表示第i组数据的结果
Sample Input
2
10 10
100 100
10 10
100 100
Sample Output
30
2791
2791
HINT
T = 10000
N, M <= 10000000
【思路】
唉??click here
【代码】
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 5 typedef long long ll; 6 const int N = 1e7+5; 7 8 ll mu[N],sum[N],su[N],sz,np[N]; 9 10 void get_mu() 11 { 12 int i,j; 13 mu[1]=1; 14 for(i=2;i<N;i++) { 15 if(!np[i]) { 16 su[++sz]=i; 17 mu[i]=-1; 18 } 19 for(j=1;j<=sz&&i*su[j]<N;j++) { 20 np[i*su[j]]=1; 21 if(i%su[j]==0) mu[i*su[j]]=0; 22 else mu[i*su[j]]=-mu[i]; 23 } 24 } 25 for(i=1;i<=sz;i++) 26 for(j=su[i];j<N;j+=su[i]) 27 sum[j]+=mu[j/su[i]]; 28 for(i=1;i<N;i++) 29 sum[i]+=sum[i-1]; 30 } 31 ll C(int n,int m) 32 { 33 int i,last; ll res=0; 34 if(n>m) swap(n,m); 35 for(i=1;i<=n;i=last+1) { 36 last=min(n/(n/i),m/(m/i)); 37 res+=(n/i)*(m/i)*(sum[last]-sum[i-1]); 38 } 39 return res; 40 } 41 int main() 42 { 43 get_mu(); 44 int T,n,m; 45 scanf("%d",&T); 46 while(T--) { 47 scanf("%d%d",&n,&m); 48 printf("%lld\n",C(n,m)); 49 } 50 return 0; 51 }
posted on 2016-03-07 10:27 hahalidaxin 阅读(395) 评论(0) 编辑 收藏 举报