A - 反素数加强版 | CQNK (nks.edu.cn)
dfs枚举质因子个数
根据d(n)(约数个数) = (r1+1)(r2+1)(r3+1)...(rn+1),求最大约数个数就行了
性质及优化:
一定是先考虑小质因子,再考虑大的
p1 < p2 < p3 < p4...<pn && r1 >= r2 >= r3 >= r4... >= rn, 把上一层的指数存下来, 这一层从1到上层指数遍历
判断是否大于n时,想想乘会不会溢出,把x * y >n改成x > n / y,或者提前算好最多可以乘多少,当前质因子最大指数为logpi(n/now)
#define int long long
int n;
int ans;
int anscnt;
int prime[20] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 47, 53, 59};
inline void dfs(int num, int now, int nxt, int cnt) {
if(prime[now] == 0) return ;
if(cnt > anscnt) {
ans = num;
anscnt = cnt;
}
if(cnt == anscnt && num < ans) {
ans = num;
}
for(re int i = 1; i <= nxt; ++ i) {
if(num > n / prime[now]) return ;
num *= prime[now];
dfs(num, now + 1, i, cnt * (i + 1));
}
}
判上界版
#define int long long
int prime[20] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 47, 53, 59};
inline void dfs(int num, int now, int nxt, int cnt) {
if(prime[now] == 0) return ;
if(cnt > anscnt) {
ans = num;
anscnt = cnt;
}
if(cnt == anscnt && num < ans) {
ans = num;
}
int op = min(nxt, (int)(log(n / now) / log(prime[now])));
for(re int i = 1; i <= op; ++ i) {
if(num > n / prime[now]) return ;
num *= prime[now];
dfs(num, now + 1, i, cnt * (i + 1));
}
}
log常数较大,整体其实还跑的慢些(tle90)