Time Limit: 2 second(s) | Memory Limit: 32 MB |
You are in an m x n grid. You are standing in position (0, 0) and in each of the other lattice points (points with integer co-ordinates) an enemy is waiting. Now you have a ray gun that can fire up to infinity and no obstacle can stop it. Your target is to kill all the enemies. You have to find the minimum number of times you have to fire to kill all of them. For a 4 x 4 grid you have to fire 13 times. See the picture below:
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case contains two integers m, n (0 ≤ m, n ≤ 109) and at least one of them will be less than or equal to 106.
Output
For each case, print the case number and the minimum number of times you have to fire to kill all the enemies.
Sample Input |
Output for Sample Input |
2 4 4 10 10 |
Case 1: 13 Case 2: 65 |
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[1000005]; 12 int ans[1000005]; 13 int flag[1000005];//记忆化,当一些数的质因子种类相同,避免重复运算 14 int fen[100]; 15 int d[1000005];//每个数的最大质因数 16 int slove(int n,int m); 17 int main(void) 18 { 19 int i,j,k; 20 fill(ans,ans+1000005,1); 21 fill(d,d+1000005,1); 22 for(i=2; i<=1000000; i++) 23 { 24 if(!prime[i]) 25 { 26 for(j=2; (i*j)<=1000000; j++) 27 { 28 prime[i*j]=true; 29 ans[i*j]*=i; 30 d[i*j]=i; 31 } 32 } 33 } 34 for(i=2; i<=1000000; i++) 35 { 36 37 if(!prime[i]) 38 { 39 ans[i]*=i; 40 d[i]=i; 41 } 42 } 43 int s; 44 scanf("%d",&k); 45 LL sum=0; 46 int n,m; 47 for(s=1; s<=k; s++) 48 { sum=0; 49 memset(flag,-1,sizeof(flag)); 50 scanf("%d %d",&n,&m); 51 if(n>m) 52 { 53 swap(n,m); 54 } 55 if(m==0)sum=0; 56 else if(n==0) 57 { 58 sum=1; 59 } 60 else 61 { sum=2; 62 for(i=1; i<=n; i++) 63 { 64 if(flag[ans[i]]!=-1) 65 { 66 sum+=flag[ans[i]]; 67 } 68 else 69 { 70 flag[ans[i]]=slove(i,m); 71 sum+=flag[ans[i]]; 72 } 73 } 74 } 75 printf("Case %d: %lld ",s,sum); 76 } 77 return 0; 78 } 79 int slove(int n,int m) 80 { 81 int i,j,k; 82 int nn=n; 83 int cnt=0; 84 while(n>1) 85 {fen[cnt++]=d[n]; 86 n/=d[n]; 87 } 88 int cc=1<<cnt; 89 LL sum=0; 90 int sum1=0; 91 for(i=1; i<cc; i++) 92 { 93 int ck=0; 94 int ak=1; 95 for(j=0; j<cnt; j++) 96 { 97 if(i&(1<<j)) 98 { 99 ak*=fen[j]; 100 ck++; 101 } 102 } 103 if(ck%2) 104 { 105 106 sum+=m/ak; 107 } 108 else sum-=m/ak; 109 } 110 return m-sum; 111 }