题目链接点这儿
很明显最长的链的长度就是x的质因子的幂和,也就是说链的形状一定是1,p1,p1*p2,p1*p2*p3,……x 其中x = p1*p2*p3……,pi均为质数。
所以本题的做法便是因数分解+有重复元素的排列公式。
下面代码
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <climits> #define up(i, lower, upper) for(int i = lower; i < upper; i++) #define down(i, lower, upper) for(int i = upper-1; i >= lower; i--) using namespace std; #define MAX_N 100010 #define INF 1<<30 typedef pair<int, int> pii; typedef pair<double, double> pdd; typedef vector<int> vi; typedef vector<pii> vpii; typedef long long ll; typedef unsigned long long ull; const double pi = acos(-1.0); const double eps = 1.0e-9; template<class T> inline bool read(T &n){ T x = 0, tmp = 1; char c = getchar(); while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar(); if(c == EOF) return false; if(c == '-') c = getchar(), tmp = -1; while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar(); n = x*tmp; return true; } template <class T> inline void write(T n) { if(n < 0) { putchar('-'); n = -n; } int len = 0,data[20]; while(n) { data[len++] = n%10; n /= 10; } if(!len) data[len++] = 0; while(len--) putchar(data[len]+48); } ///--------------------------------------- ll p[30]; int prime[(1<<20)+5], p_len = 0; bool used[(1<<20)+5] = { false }; inline void make_prime() { up(i, 2, 1<<20) { if(used[i]) continue; used[i] = true; prime[p_len++] = i; for(int j = i; j <= 1024; j += i) used[j] = true; } } inline void permutation() { ll ans; up(i, 1, 20+1) { ans = 1; up(j, 2, i+1) ans *= (ll)j; p[i] = ans; } } int main() { make_prime(); permutation(); int n, cnt, mi[25], tmp, len; while(read(n)){ cnt = 0, tmp = n, len = 0; memset(mi, 0, sizeof mi); for(int i = 0; prime[i] <= sqrt(tmp) && i < p_len; i++) { if(tmp % prime[i] == 0) cnt++; while(tmp%prime[i] == 0) len++, mi[cnt-1]++, tmp/=prime[i]; } if(tmp != 1) cnt++, len++, mi[cnt-1]++; ll ans = p[len]; up(i, 0, cnt) ans/=p[mi[i]]; write(len), putchar(' '), write(ans), putchar('\n'); } return 0; }