洛谷P1072 Hankson的趣味题
这是个NOIP原题...
题意:
给定 a b c d 求 gcd(a, x) = b && lcm(c, x) = d 的x的个数。
可以发现一个朴素算法是从b到d枚举,期望得分50分。
(为什么lyd大佬的暴力就是90...)
有个要点就是所求的x必定为d的约数。
然后根据lcm和gcd的性质,拆成质因数。
x的每个质因数个数是有范围的,可以求出来。
然后乘起来就行了。
注意要分类讨论,别用书上写的,有毒。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 const int N = 100010; 3 4 int p[N], top; 5 bool vis[N]; 6 7 inline void getp(int b) { 8 for(int i = 2; i <= b; i++) { 9 if(!vis[i]) { 10 p[++top] = i; 11 } 12 for(int j = 1; j <= top && i * p[j] <= b; j++) { 13 vis[i * p[j]] = 1; 14 if(i % p[j] == 0) { 15 break; 16 } 17 } 18 } 19 return; 20 } 21 22 inline void clear() { 23 24 return; 25 } 26 27 inline int getcnt(int pr, int a) { 28 if(a % pr) { 29 return 0; 30 } 31 int ans = 1; 32 a /= pr; 33 while(a % pr == 0) { 34 ans++; 35 a /= pr; 36 } 37 return ans; 38 } 39 40 inline void solve() { 41 int a, b, c, d; 42 scanf("%d%d%d%d", &a, &b, &c, &d); 43 int d1 = d, ans = 1; 44 int ta, tb, tc, td; 45 for(int i = 1; i <= top && p[i] <= d1; i++) { 46 if(d1 % p[i]) { 47 continue; 48 } 49 td = 1; 50 d1 /= p[i]; 51 while(d1 % p[i] == 0) { 52 d1 /= p[i]; 53 td++; 54 } 55 ta = getcnt(p[i], a); 56 tb = getcnt(p[i], b); 57 tc = getcnt(p[i], c); 58 if(tc < td) { // ans = td 59 if((ta > tb && tb == td) || (ta == tb && tb <= td)) { 60 ; 61 } 62 else { 63 printf("0\n"); 64 return; 65 } 66 } 67 else if(tc == td) { // ans <= td 68 if(ta > tb && tb <= td) { 69 ; 70 } 71 else if(ta == tb && tb <= td) { 72 ans *= (td - tb + 1); 73 } 74 else { 75 printf("0\n"); 76 return; 77 } 78 } 79 } 80 if(d1 > 1) { 81 td = 1; 82 ta = getcnt(d1, a); 83 tb = getcnt(d1, b); 84 tc = getcnt(d1, c); 85 if(tc < td) { // ans = td 86 if((ta > tb && tb == td) || (ta == tb && tb <= td)) { 87 ; 88 } 89 else { 90 printf("0\n"); 91 return; 92 } 93 } 94 else if(tc == td) { // ans <= td 95 if(ta > tb && tb <= td) { 96 ; 97 } 98 else if(ta == tb && tb <= td) { 99 ans *= (td - tb + 1); 100 } 101 else { 102 printf("0\n"); 103 return; 104 } 105 } 106 } 107 printf("%d\n", ans); 108 return; 109 } 110 111 int main() { 112 getp(100000); 113 int T; 114 scanf("%d", &T); 115 while(T--) { 116 solve(); 117 if(T) { 118 clear(); 119 } 120 } 121 122 return 0; 123 }