求比N小的因数最多的数,因数相同时取较小的的。(N<=10^80)
没想法的题目,没想到是搜索。。
首先因子数目 f[i] = ∏(p[i]+1) ,p[i]是所有质因数的个数,这个应该都知道。如果要使因子最多并且数最小,不会用到太大的质数,这个我也不知道怎么证明。。原题解也没有证明。。。
用一个四元组[K,F,N,A[]]表示数K有F个因数,包含N个质因数,每个质因数P[i]分别有A[i]个。然后搜索就可以了,添加一个已有质数A[i],四元组转化为[K*P[i],F/(A[i]+1)*(A[i]+2),N,A[i]+1],添加一个新的质数A[i],四元组转化为,[K*P[i],F*2,N+1,A[i]=1]。
用map存所有的F对应的K,F相同时保留较小的K。
直接做会超时,因为搜索中数是一直递增的,把结果存下来然后离线边搜边更新结果就A了,估计是因为case不多但都是大数据。。。
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <algorithm> 5 #include <map> 6 #include <queue> 7 #include<string> 8 #include<iostream> 9 #define MAXN 200 10 using namespace std; 11 typedef long long LL; 12 const int BMOD = 100000000; 13 const int maxl = (MAXN>>3)+1; 14 struct bign{ 15 int s[maxl], len; 16 void init(){memset(s, 0, sizeof s); len = 1;} 17 void clean(){while(len > 1 && !s[len-1]) --len;} 18 bign(){init();} 19 bign(int num){*this = num;} 20 bign(const char *num){*this = num;} 21 bign operator = (int num) { 22 char s[maxl]; 23 sprintf(s, "%d", num); 24 return *this = s; 25 } 26 bign operator = (const char *buf) { 27 init(); 28 int l = strlen(buf); 29 for(int i = 0, j = l - 1; i < l; ++ i, -- j) 30 s[j >> 3] = s[j >> 3] * 10 + buf[i] - '0'; 31 len = (l >> 3) + 1; 32 clean(); 33 return *this; 34 } 35 bign operator + (const bign b) { 36 bign c; c.len = 0; 37 int g = 0; 38 for (int i = 0; g || i < max(len, b.len); i++) { 39 c.s[c.len] = g; 40 if(i < len)c.s[c.len] += s[i]; 41 if(i < b.len)c.s[c.len] +=b.s[i]; 42 g = c.s[c.len]/BMOD, c.s[c.len] %= BMOD, c.len++; 43 } 44 return c; 45 } 46 bign operator * (const bign b) { 47 bign c; 48 c.len = len + b.len; 49 LL lin; 50 for (int i = 0; i < len; i++) 51 for (int j = 0; j < b.len; j++){ 52 lin = (LL)s[i] * b.s[j] + c.s[i+j]; 53 c.s[i+j] = lin % BMOD; 54 c.s[i+j+1] += lin / BMOD; 55 } 56 for (int i = 0; i < c.len - 1; i++) c.s[i+1] += c.s[i] / BMOD, c.s[i] %= BMOD; 57 c.clean(); 58 return c; 59 } 60 bool operator <(const bign b) const{ 61 if(len != b.len) return len < b.len; 62 for (int i = len - 1; i >= 0; i--) 63 if (s[i] != b.s[i]) return s[i] < b.s[i]; 64 return false; 65 } 66 bool operator <=(const bign b) const {return !(b < *this);} 67 68 void print() { 69 for(int i = len - 1; i >= 0; i--) { 70 if (i == len - 1) printf("%d", s[i]); 71 else printf("%08d", s[i]); 72 } 73 } 74 }; 75 76 struct stt{ 77 bign k; 78 LL f; 79 int n,a[MAXN]; 80 stt(){} 81 stt(bign kk, LL ff, int nn) {k = kk, f= ff, n = nn;} 82 }; 83 84 struct ans{ 85 bign in, res; 86 LL f; 87 }; 88 map<LL, bign> mp; 89 vector<ans> vec; 90 bign maxp, pri[MAXN]; 91 int prs; 92 //pri[i]和stt里的a[i]是对应的,a[i]是pri[i]的个数 93 void init() { 94 prs = 0; 95 for (int i = 2, j, flag; i < MAXN; i++) { 96 for (flag = 1,j = 2; j < i; j++) 97 if (i % j == 0) flag = 0; 98 if (flag) pri[prs++] = i; 99 } 100 } 101 bool canadd(stt st) { 102 if (maxp < st.k) return false; 103 if (mp.find(st.f) == mp.end() || st.k < mp[st.f]){ 104 mp[st.f] = st.k; 105 return true; 106 } 107 return false; 108 } 109 void updateans(stt st) { 110 for (int i = 0; i < vec.size(); i++) { 111 if (st.k <= vec[i].in && (st.f > vec[i].f || st.f == vec[i].f && st.k < vec[i].res)) 112 vec[i].res = st.k, vec[i].f = st.f; 113 } 114 } 115 void bfs(){ 116 queue<stt> q; 117 mp.clear(); 118 mp[1] = 1; 119 q.push(stt(1, 1, 0)); 120 while (!q.empty()) { 121 stt ost = q.front(); q.pop(); 122 updateans(ost); 123 //添加已有质数 124 for (int i = 0 ; i < ost.n; i++) { 125 stt nst = ost; 126 nst.k = ost.k * pri[i]; 127 nst.f = ost.f / (ost.a[i]+1) * (ost.a[i]+2); 128 nst.a[i]++; 129 if (canadd(nst)) q.push(nst); 130 } 131 //添加还未添加的质数 132 stt nst = ost; 133 nst.k = ost.k * pri[ost.n]; 134 nst.f = ost.f * 2; 135 nst.a[nst.n++] = 1; 136 if (canadd(nst)) q.push(nst); 137 } 138 } 139 char s[MAXN]; 140 int main() { 141 //freopen("test.in","r",stdin); 142 init(); 143 maxp = 0; 144 vec.clear(); 145 mp.clear(); 146 while (scanf("%s", s) != EOF) { 147 ans a; a.in = s, a.res = 1, a.f = 1; 148 if (maxp < a.in) maxp = a.in; 149 vec.push_back(a); 150 } 151 bfs(); 152 for (int i = 0; i < vec.size(); i++) 153 vec[i].res.print(), printf(" %I64d\n",vec[i].f); 154 return 0; 155 }