详见:《算法导论》
HDU 4344
1、长度是N的因子(且大于1小于N),集合中的元素得两两互质
2、为了尽可能多的选出,每个L的质因子应当只包含N的一个质因子,L是一个质因子的整数次,所以K的值就是N中不同质因子的个数
3、要想和最大,那么使得每个L最大,只要使得质因子的指数最大即可
所以用pollard_rho分解N的质因数,然后统计不同的质因子个数K,以及计算所有相同质因子乘积的和S
特殊情况:如果N本身是某个质数的整数i次幂,那么K只能等于1,因为L要小于N,所以L最大为该质数的i-1次幂
以前poj上用过这个模板。。。放在这道题上wa到爆了。。。最后发现是没注意上面这种情况。。。
吐嘈一下,恶心的HDOJ,不能用lld。。。。!!
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <ctime> #include <queue> #include <map> #include <sstream> #define CL(arr, val) memset(arr, (val), sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) ((l) + (r)) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) ((x) > 0 ? (x) : -(x)) typedef long long LL; const double eps = 1e-8; //const int inf = ~0u>>2; using namespace std; const int C = 16381; const LL inf = 1<<22; map<LL, LL> mp; LL gcd(LL a, LL b) { return b ? gcd(b, a%b) : a; } LL mod_mul(LL a, LL b, LL n) { LL res = 0; while(b > 0) { if(b&1) {res = (res + a); if(res >= n) res -= n;} a = (a + a); if(a >= n) a -= n; b >>= 1; } return res; } LL mod_exp(LL a, LL b, LL n) { LL res = 1; while(b > 0) { if(b&1) res = mod_mul(res, a, n); a = mod_mul(a, a, n); b >>= 1; } return res; } bool miLLer_rabin(LL n) { if(n == 2 || n == 3 || n == 5 || n == 7 || n == 11) return true; if(n == 1 || !(n%2) || !(n%3) || !(n%5) || !(n%7) || !(n%11)) return false; LL x, pre, u; int i, j, k = 0; u = n - 1; while(!(u&1)) { k++; u >>= 1; } srand((LL)time(0)); for(i = 0; i < 5; ++i) { //5次足够AC了 x = rand()%(n-2) + 2; if((x%n) == 0) continue; x = mod_exp(x, u, n); pre = x; for(j = 0; j < k; ++j) { x = mod_mul(x, x, n); if(x == 1 && pre != 1 && pre != n-1) return false; pre = x; } if(x != 1) return false; } return true; } LL poLLard_rho(LL n, LL c) { LL x, y, d; LL i, k; i = 1; k = 2; srand((LL)time(0)); x = rand()%(n-1) + 1; y = x; while(1) { i ++; x = (mod_exp(x, 2, n) + c) % n; d = gcd(y - x + n, n); if(d != 1 && d != n) return d; if(x == y) return n; if(i == k) { y = x; k *= 2; } } } void factor(LL n, LL c) { if(n <= 1) return ; LL r, d; if(miLLer_rabin(n)) { if(mp[n] == 0) mp[n] = n; else mp[n] *= n; return ; } r = poLLard_rho(n, c--); d = n/r; factor(d, c); factor(r, c); } int main() { //freopen("data.in", "r", stdin); int t; LL n, k, sum; scanf("%d", &t); while(t--) { cin >> n; if(miLLer_rabin(n)) {cout << 1 << " " << 1 << endl;} else { sum = 0; k = 0; mp.clear(); factor(n, C); map<LL, LL>::iterator it; for(it = mp.begin(); it != mp.end(); ++it) { k++; sum += it->second; } it = mp.begin(); if(k == 1) cout << k << " " << sum/it->first << endl; else cout << k << " " << sum << endl; } } return 0; }