UVa 10892 - LCM Cardinality
Published on 2016-02-16描述
给定正整数 ,统计有多少个整数对 ,满足 。
样例输入
2 12 24 101101291 0
样例输出
2 2 12 8 24 11 101101291 5
分析
首先我们得明白 的一些事情。对于正整数 ,有:
就意味着对于 的每个 , 和 的因子 的指数均不大于 ,但一定有一个的指数等于 。我们通过确定 和 的每一个因子 的指数取值情况,最后得到所有可行的整数对。虽然题目要求 ,但是单凭一个因数的指数取值无法限制,所以我们先允许重复计算,后面再去除重复。
如果 的因子 的指数是 , 的因子 的指数可以取 ;如果 是 , 可以取 ,加上 都取 的情况,一共有 种情况。
对于每一个 ,都有 种情况,那么根据乘法原理,每个因数的情况数乘起来就行。但是 被算了两次,而 只被算了一次(它应该被算两次!),所以答案是 ,又因为答案是奇数,所以也写作:。
剩下的就是分解质因数,并且运用了线性筛法,不会的自行百度,注意我们只试到
代码
// Created by Sengxian on 2/16/16. // Copyright (c) 2015年 Sengxian. All rights reserved. // UVa 10892 数学 分解质因数 LCM #include <algorithm> #include <iostream> #include <cctype> #include <climits> #include <cstring> #include <cstdio> #include <cmath> #include <vector> #include <stack> #include <queue> #define br putchar('\n'); using namespace std; inline int ReadInt() { int n = 0, ch = getchar(); while(!isdigit(ch)) ch = getchar(); while(isdigit(ch)) n = (n << 3) + (n << 1) + ch - '0', ch = getchar(); return n; } const int maxn = 45000 + 3; bool isPrime[maxn]; vector<int> primes; void sieve() { fill(isPrime, isPrime + maxn, true); for(int i = 2; i < maxn; ++i) { if(isPrime[i]) primes.push_back(i); for(int j = 0; j < primes.size() && i * primes[j] < maxn; ++j) { isPrime[i * primes[j]] = false; if(i % primes[j] == 0) break; } } } int n; int main() { sieve(); while(n = ReadInt(), n) { printf("%d ", n); int s = sqrt(n), ans = 1; for(int i = 0; i < primes.size() && primes[i] <= s; ++i) { int cnt = 0; while(n % primes[i] == 0) cnt++, n /= primes[i]; ans *= cnt * 2 + 1; //a 或 b 有一个为 cnt,另一取 0 - cnt 。所以有 cnt * 2 + 1 种情况! } if(n > 1) ans *= 3; //大质数 printf("%d\n", ans / 2 + 1); //(x, x) 只算了一次,ans 是奇数故直接 / 2 } return 0; }
附加输入
2 12 1000000 12345676 87675612 1251562 9412 6537 123 12 3244 56342 1233 344333 98123 1 2 3 243 123999 0
附加输出
2 2 12 8 1000000 85 12345676 68 87675612 23 1251562 41 9412 23 6537 5 123 5 12 8 3244 8 56342 41 1233 8 344333 14 98123 2 1 1 2 2 3 2 243 6 123999 5