高精度+搜索+质数 BZOJ1225 [HNOI2001] 求正整数

时间:2021-01-31 08:24:59
 // 高精度+搜索+质数 BZOJ1225 [HNOI2001] 求正整数
// 思路:
// http://blog.csdn.net/huzecong/article/details/8478689
// M=p1^(t1)*p2^(t2)*p3^(t3)....
// N=(t1+1)*(t2+1)*(t3+1)*(t4+1)...
// 所以t最大到16,就可以暴力搜索了 #include <bits/stdc++.h>
using namespace std;
#define LL long long
const double inf = 123456789012345.0;
const LL MOD =100000000LL;
const int N =1e5+;
#define clc(a,b) memset(a,b,sizeof(a))
const double eps = 1e-;
void fre(){freopen("in.txt","r",stdin);}
void freout() {freopen("out.txt","w",stdout);}
inline int read() {int x=,f=;char ch=getchar();while(ch>''||ch<'') {if(ch=='-') f=-;ch=getchar();}while(ch>=''&&ch<='') {x=x*+ch-'';ch=getchar();}return x*f;} int n;
const int M=;
const int p[]= {, , , , , , , , , , , , , , , };
double Log[];
class bignum {
public:
LL num[N];
int tot;
bignum() {}
bignum(LL x) {
clear();
while (x) num[tot++] = x % MOD, x /= MOD;
}
void clear(){
tot = ;
for (int i = ; i < N; ++i) num[i] = 0LL;
}
void operator *= (const int &x){
for (int i = ; i < tot; ++i) num[i] *= x;
for (int i = ; i < tot; ++i)
if (num[i] >= MOD) {
num[i + ] += num[i] / MOD;
num[i] %= MOD;
}
while (num[tot]) {
if (num[tot] >= MOD) {
num[tot + ] += num[tot] / MOD;
num[tot] %= MOD;
}
++tot;
}
}
void print() {
printf("%lld", num[tot - ]);
for (int i = tot - ; i >= ; --i)
printf("%08lld", num[i]);
}
}ans(); int t[],ct[];
double mn;
int cnt; void dfs(int d,int x,int m,double tem){
if(tem>mn) return;
if(x==){
if(tem<mn){
mn=tem,cnt=d-;
for(int i=;i<d;i++) t[i]=ct[i];
}
}
for(int i=;i*i<=x&&i<=m;i++){
if(!(x%i)){
if(i!=){
ct[d]=i;
dfs(d+,x/i,i,tem+(double)Log[d]*(i-));
}
if(x/i<=m&&x/i!=i){
ct[d]=x/i;
dfs(d+,i,x/i,tem+(double)Log[d]*(x/i-));
}
}
}
} int main(){
scanf("%d",&n);
for(int i=;i<=;i++) Log[i]=(double)log(p[i]);
mn=inf;
cnt=;
dfs(,n,n,0.0);
for(int i=;i<=cnt;i++){
for(int j=t[i]-;j>;j--){
ans*=p[i];
}
}
ans.print();
return ;
}