对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。
标签:
对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。
第一行一个整数n,接下来n行每行五个整数,分别表示a、b、c、d、k
共n行,每行一个整数表示满足要求的数对(x,y)的个数
100%的数据满足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 using namespace std; 5 6 #define maxn 100010 7 int mu[maxn],prime[maxn],tot; bool exist[maxn]; 8 9 inline void ready() 10 { 11 mu[1] = 1; 12 for (int i = 2;i <= 50000;++i) 13 { 14 if (!exist[i]) prime[++tot] = i,mu[i] = -1; 15 for (int j = 1;j <= tot&&i*prime[j] <= 50000;++j) 16 { 17 exist[i*prime[j]] = true; 18 if (i % prime[j] == 0) { mu[i*prime[j]] = 0; break; } 19 mu[i*prime[j]] = -mu[i]; 20 } 21 } 22 for (int i = 1;i <= 50000;++i) mu[i] += mu[i-1]; 23 } 24 25 inline int work(int a,int b,int k) 26 { 27 a /= k; b /= k; 28 if (a > b) swap(a,b); 29 int ret = 0,pos; 30 for (int i = 1;i <= a;i = pos+1) 31 { 32 pos = min(a/(a/i),b/(b/i)); 33 ret += (mu[pos]-mu[i-1])*(a/i)*(b/i); 34 } 35 return ret; 36 } 37 38 int main() 39 { 40 freopen("2301.in","r",stdin); 41 freopen("2301.out","w",stdout); 42 ready(); 43 int T; scanf("%d",&T); 44 while (T--) 45 { 46 int a,b,c,d,k,ans; 47 scanf("%d %d %d %d %d",&a,&b,&c,&d,&k); 48 ans = work(a-1,c-1,k)+work(b,d,k)-work(a-1,d,k)-work(b,c-1,k); 49 printf("%d\n",ans); 50 } 51 fclose(stdin); fclose(stdout); 52 return 0; 53 }
标签:
原文地址:http://www.cnblogs.com/mmlz/p/4275792.html