知道 n 所有质因数后,通过搜索求 n 所有因数
void dfs(int dept,LL ans = 1)
{
if(dept == cnt)
{
fac[ct++] = ans;
return;
}
for(int i=0;i<=num[dept];i++)
{
dfs(dept+1,ans);
ans *= pri[dept];
}
}
而且一个反素数的所有质因子必然是从 2 开始的连续若干个质数
因为反素数是保证约数个数为的这个数尽量小
所以说
int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
就可以了
来个模板题
http://codeforces.com/problemset/problem/27/E
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
int n, ans;
// 为什么要拿前16个素数 因为它们各取一个相乘够1e18 并且是最小的
int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
// dept 要用到多少个质因数
// ans 最终拼出的数字
// tmp 当前拼出的数字
// num 有多少个因数
// 一开始是均匀摊开的 大家都是一个 后来慢慢开始往前面浓缩
void dfs(int dept, int tmp, int num)
{
if(num > n) return ;
// cout << "要用到多少个质因数" << dept << ' ' << "当前拼出的数字" << tmp << ' ' << "有多少个因数" << num << endl;
if(num == n && tmp < ans) ans = tmp;
// long long 范围 2^64 - 1
for(int i = 1; i <= 64; i ++ )
{
// 会炸掉 long long
// if(tmp * p[dept] > ans) break;
if(tmp > ans / p[dept]) break;
dfs(dept + 1, tmp * p[dept], num * (i + 1));
tmp *= p[dept];
}
return ;
}
void solve()
{
cin >> n;
ans = 0x3f3f3f3f3f3f3f3f;
// 一开始 根节点数字是1 0个质因数被用 当前拼出的数字为1 只有一个因数
dfs(0, 1, 1);
cout << ans << endl;
return ;
}
int32_t main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int T = 1;
// int T; cin >> T;
for(int i = 1; i <= T; i ++ )
{
solve();
}
return 0;
}
求n以内的最多因子数的数 n=1e16
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1562
本来是浙大的题 但浙大OJ好像搬到PTA上面去了
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
int n, ans = -1, vis = -1;
int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
// 用第几个素数 当前的值 有几个因数
// 为什么 24 和 30 都是 8 个因子 输出的是30
// 因为30 = 2 * 3 * 5 分布的很散 所以先出来
// 24 = 2 * 2 * 2 * 3 后来才聚出来的 然而因为 ans 并不会更大所以不更新
void dfs(int x, int y, int z)
{
if(y > n) return ;
if(z > ans) ans = z, vis = y;
for(int i = 1; i <= 64; i ++ )
{
if(y > n / p[x]) break;
dfs(x + 1, y * p[x], z * (i + 1));
y *= p[x];
}
}
void solve()
{
cin >> n;
// for(int i = 1; i <= 100; i ++ )
// {
// n = i;
dfs(0, 1, 1);
cout << vis << endl;
// cout << n << ' ';
// cout << vis << ' ' << ans << endl;
// }
return ;
}
int32_t main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int T = 1;
// int T; cin >> T;
for(int i = 1; i <= T; i ++ )
{
solve();
}
return 0;
}
为什么今天学反素数呢?因为要补题
https://ac.nowcoder.com/acm/contest/24809/G
#include <bits/stdc++.h>
#define int unsigned long long
#define endl '\n'
using namespace std;
int n, ans;
int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
// 用第几个素数 当前的值 有几个因数
void dfs(int x, int y, int z)
{
if(y > n) return ;
if(z > ans) ans = z;
for(int i = 1; i <= 64; i ++ )
{
if(y > n / p[x]) break;
dfs(x + 1, y * p[x], z * (i + 1));
y *= p[x];
}
}
void solve()
{
ans = 0;
cin >> n;
dfs(0, 1, 1);
cout << ans << endl;
return ;
}
int32_t main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
// int T = 1;
int T; cin >> T;
for(int i = 1; i <= T; i ++ )
{
solve();
}
return 0;
}
写的巨好
https://blog.csdn.net/ACdreamers/article/details/25049767