GCD(hdu1695)

GCD

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9696    Accepted Submission(s): 3623


Problem Description
Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k. GCD(x, y) means the greatest common divisor of x and y. Since the number of choices may be very large, you're only required to output the total number of different number pairs.
Please notice that, (x=5, y=7) and (x=7, y=5) are considered to be the same.

Yoiu can assume that a = c = 1 in all test cases.
 
Input
The input consists of several test cases. The first line of the input is the number of the cases. There are no more than 3,000 cases.
Each case contains five integers: a, b, c, d, k, 0 < a <= b <= 100,000, 0 < c <= d <= 100,000, 0 <= k <= 100,000, as described above.
 
Output
For each test case, print the number of choices. Use the format in the example.
 
Sample Input
2
1 3 1 5 1
1 11014 1 14409 9
 
Sample Output
Case 1: 9
Case 2: 736427
思路:容斥+欧拉函数;
n,m最大公约数为k,那么就转换成找(n/k,m/k)互质的对数;那么这个会想到欧拉函数,但是欧拉函数可以解决,n,m相等的情况,当n,m不等的时候
那么直接用容斥跑(1,min(n,m))在(1,max(m,n))中互质的数的个数,最后再减掉oula[min(n,m)],这是重复的,然后再加上1也就是(1,1)是没重,但在oula[]中减了
  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<string.h>
  5 #include<stdlib.h>
  6 #include<queue>
  7 #include<math.h>
  8 #include<vector>
  9 using namespace std;
 10 typedef long long LL;
 11 bool prime[100005];
 12 int ans[100005];
 13 int flag[100005];
 14 int fen[100];
 15 int d[100005];
 16 LL  oula[100005];
 17 int slove(int n,int m);
 18 int main(void)
 19 {
 20         int i,j,k;
 21         fill(ans,ans+100005,1);
 22         fill(d,d+100005,1);
 23         int c=0;
 24         for(i=0; i<=100000; i++)oula[i]=i;
 25         for(i=2; i<=100000; i++)
 26         {
 27                 if(!prime[i])
 28                 {
 29                         for(j=2; (i*j)<=100000; j++)
 30                         {
 31                                 prime[i*j]=true;
 32                                 ans[i*j]*=i;
 33                                 d[i*j]=i;
 34                         }
 35                 }
 36         }
 37         oula[0];
 38         oula[1]=1;
 39         for(i=2; i<=100000; i++)
 40         {
 41                 if(!prime[i])
 42                 {
 43                         ans[i]*=i;
 44                         d[i]=i;
 45                         for(j=1; (LL)i*(LL)j<=100000; j++)
 46                         {
 47                                 oula[i*j]/=i;
 48                                 oula[i*j]*=(i-1);
 49                         }
 50                 }
 51         }
 52         int s;
 53         scanf("%d",&k);
 54         LL sum=0;
 55         int n,m;
 56         for(i=2; i<=100000; i++)oula[i]+=oula[i-1];
 57         for(s=1; s<=k; s++)
 58         {
 59                 sum=0;
 60                 int xx,yy,vv;
 61                 memset(flag,-1,sizeof(flag));
 62                 scanf("%d %d %d %d %d",&xx,&n,&yy,&m,&vv);
 63                 if(vv>n||vv>m||vv==0)
 64                 {
 65                         printf("Case %d: ",s);
 66                         printf("0
");
 67                 }
 68                 else
 69                 {
 70                         if(n>m)
 71                         {
 72                                 swap(n,m);
 73                         }
 74                         n/=vv;
 75                         m/=vv;
 76                         sum=0;
 77                         for(i=1; i<=n; i++)
 78                         {
 79                                 if(flag[ans[i]]!=-1)
 80                                 {
 81                                         sum+=flag[ans[i]];
 82                                 }
 83                                 else
 84                                 {
 85                                         flag[ans[i]]=slove(i,m);
 86                                         sum+=flag[ans[i]];
 87                                 }
 88                         }
 89                         //printf("%lld %lld
",oula[5],sum);
 90                         printf("Case %d: %lld
",s,sum-oula[min(n,m)]+1);
 91                 }
 92         }
 93         return 0;
 94 }
 95 int slove(int n,int m)
 96 {
 97         int i,j,k;
 98         int nn=n;
 99         int cnt=0;
100         while(n>1)
101         {
102                 fen[cnt++]=d[n];
103                 n/=d[n];
104         }
105         int cc=1<<cnt;
106         LL sum=0;
107         int sum1=0;
108         for(i=1; i<cc; i++)
109         {
110                 int ck=0;
111                 int ak=1;
112                 for(j=0; j<cnt; j++)
113                 {
114                         if(i&(1<<j))
115                         {
116                                 ak*=fen[j];
117                                 ck++;
118                         }
119                 }
120                 if(ck%2)
121                 {
122                         sum+=m/ak;
123                 }
124                 else sum-=m/ak;
125         }
126         return m-sum;
127 }
油!油!you@
原文地址:https://www.cnblogs.com/zzuli2sjy/p/5766148.html