hdu 4430 二分+枚举

/*
二分+枚举
枚举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;}

posted @ 2014-10-17 21:36  HYDhyd  阅读(134)  评论(0编辑  收藏  举报