hdu 4430 二分+枚举

时间:2023-03-08 17:59:19
/*
二分+枚举
枚举k会超时,枚举r还要优化,有可能会超64
*/
#include<stdio.h>
#include<math.h>
#define ll __int64
#define inf 1000000000000
#define ii 1000000000000000000
ll endd,enddk,enddr;
void update(ll k,ll r) {
if(k*r<endd) {
endd=k*r;
enddk=k;
enddr=r;
}
if(k*r==endd) {
if(enddr>r) {
enddr=r;
enddk=k;
}
}
return ;
}
ll power(ll k,ll f) {
ll sum=1,i;
for(i=1;i<=f;i++)
sum*=k;
return sum;
}
ll erfen(ll r,ll left,ll right,ll n) {
while(left<=right) {
ll mid=(left+right)/2;
ll sum=power(mid,r)-1;
if(sum==n*(mid-1))return mid;
// printf("%I64d\n",sum);
if(sum<n*(mid-1))
left=mid+1;
else
right=mid-1;
}
return -1;
}
int main(){
ll n,i,k;
while(scanf("%I64d",&n)!=EOF) {
endd=n;enddr=1;enddk=n-1;
for(i=2;i<=40;i++) {//必须从2开始,从一开始会超ll
ll kk=(ll)pow(1.0*n,1/(1.0*i))+1;//重点优化
k=erfen(i+1,2,kk,n);
if(k!=-1)
update(k,i);
k=erfen(i+1,2,kk,n+1);
if(k!=-1)
update(k,i);
// printf("k2=%I64d\n",k);
// if(i==3)break;
}
printf("%I64d %I64d\n",enddr,enddk);
}
return 0;}