题目大意:给你5个数a,b,c,d,k。x属于[a,b]y属于[c,d]。 问你有多少对(x,y)的公约数为k。 注意(x,y)和 (y,x)视为同一对。
x是[1,b],y是[1,d],求GCD(x,y)=k的对数(x,y无序)
对x,y都除以k,则求GCD(x,y)=1
此时枚举x,问题转化为[1,d]区间内与x互素的数字个数,这个问题是hdu 4135
有一个特殊的地方是x,y无序,对于这点只要保证x始终小于y就可以了
注意特判k==0的情况
2 1 3 1 5 1 1 11014 1 14409 9
Case 1: 9 Case 2: 736427HintFor the first sample input, all the 9 pairs of numbers are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> using namespace std; int s[100020],k; void init(int m) { k=0; for(int i=2; i*i<=m; i++) { if(m%i==0) { s[k++]=i; while(m%i==0) m/=i; } } if(m>1) s[k++]=m; } long long quc(int m) { int t=0,p[100020],z; long long sum=0; p[t++]=-1; for(int i=0; i<k; i++) { z=t; for(int j=0; j<z; j++) { p[t++]=p[j]*s[i]*(-1); } } for(int i=1; i<t; i++) { sum+=m/p[i]; } return sum; } int main() { int n,a,b,c,d,m,g=0; long long sum; scanf("%d",&n); while(n--) { sum=0; scanf("%d %d %d %d %d",&a,&b,&c,&d,&m); g++; if(m==0||m>b||m>d) {printf("Case %d: 0\n",g); continue; } b=b/m; d=d/m; if(b>d) swap(b,d); for(int i=1; i<=b; i++) { init(i); sum+=d-quc(d)-i+1+quc(i-1); //printf("%d %d\n",quc(i-1),quc(d)); } printf("Case %d: %I64d\n",g,sum); } }