LOJ 1341 Aladdin and the Flying Carpet(质因子分解)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1341
题意:给两个数a,b,求满足c * d = a且c>=b且d>=b的c, d二元组对数,(c, d)和(d, c)属于同一种情况。
思路:根据唯一分解定理,先将a唯一分解,则a的所有正约数的个数为num = (1 + a1) * (1 + a2) *...* (1 + ai),这里的ai是素因子的指数。现在我们知道了a的因子个数为num,假设因子从小到大排列为
X1,X2,...,Xnum 因为是求二元组,所以num先除以2,然后减去那些比b小的因子即可(比b小的一定和比较大的组合,所以不用考虑很大的情况)。
code:
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 typedef long long LL; 6 const int MAXN = 1000000; 7 8 int prime[MAXN + 1]; 9 10 void getPrime() 11 { 12 memset(prime, 0, sizeof(prime)); 13 for (int i = 2; i <= MAXN; ++i) { 14 if (!prime[i]) prime[++prime[0]] = i; 15 for (int j = 1; j <= prime[0] && prime[j] <= MAXN / i; ++j) { 16 prime[prime[j] * i] = 1; 17 if (i % prime[j] == 0) break; 18 } 19 } 20 } 21 22 LL factor[1000][2]; 23 int fatCnt; 24 25 int getFactors(LL x) 26 { 27 fatCnt = 0; 28 LL tmp = x; 29 for (int i = 1; i <= prime[0] && prime[i] * prime[i] <= tmp; ++i) { 30 factor[fatCnt][1] = 0; 31 if (tmp % prime[i] == 0) { 32 factor[fatCnt][0] = prime[i]; 33 while (tmp % prime[i] == 0) { 34 ++factor[fatCnt][1]; 35 tmp /= prime[i]; 36 } 37 ++fatCnt; 38 } 39 } 40 if (tmp != 1) { 41 factor[fatCnt][0] = tmp; 42 factor[fatCnt++][1] = 1; 43 } 44 LL ret = 1; 45 for (int i = 0; i < fatCnt; ++i) { 46 ret *= (1L + factor[i][1]); 47 } 48 return ret; 49 } 50 51 int main() 52 { 53 getPrime(); 54 int nCase; 55 scanf("%d", &nCase); 56 for (int cnt = 1; cnt <= nCase; ++cnt) { 57 LL a, b; 58 scanf("%lld %lld", &a, &b); 59 if (b * b > a) { 60 printf("Case %d: 0\n", cnt); 61 continue; 62 } 63 LL num = getFactors(a); 64 num /= 2; 65 for (int i = 1; i < b; ++i) { 66 if (a % i == 0) --num; 67 } 68 printf("Case %d: %lld\n", cnt, num); 69 } 70 return 0; 71 }