hdu 4430 Yukari's Birthday

思路:

分析知道1<=r<40;所以可以枚举r,之后再二分k。

代码如下:

 

 1 #include<iostream>

 2 #include<stdio.h>

 3 #include<algorithm>

 4 #include<iomanip>

 5 #include<cmath>

 6 #include<cstring>

 7 #include<vector>

 8 #define ll __int64

 9 #define M 2011

10 using namespace std;

11 ll m,rr,kk,mi,n;

12 ll pows(ll a,ll b)

13 {

14     ll ans=1;

15     while(b){

16         if(b&1) ans=ans*a;

17         b>>=1;

18         a*=a;

19     }

20     return ans;

21 }

22 int fun(ll a,ll r)

23 {

24     ll ans=(pows(a,r+1)-a)/(a-1);

25     if(ans==n||ans==n-1){

26         if(mi>r*a) return 2;

27         else return 1;

28     }

29     else if(ans>n) return 3;

30     return 0;

31 }

32 int main(){

33     ll i,j,k,r,le,ri,mid;

34     while(scanf("%I64d",&n)!=EOF){

35         r=(ll)(log2(n+2)+1)-1;

36         rr=1;kk=n-1;mi=n-1;

37         for(i=2;i<=r;i++){

38             k=(ll)pow((double)n,1.0/i);//一定满足k^i<n

39             le=2;ri=k;

40             while(le<=ri){

41                 mid=(le+ri)/2;

42                 int t=fun(mid,i);

43                 if(t==2){

44                     rr=i;

45                     kk=mid;

46                 }

47                 if(t) ri=mid-1;

48                 else le=mid+1;

49             }

50 

51         }

52         printf("%I64d %I64d\n",rr,kk);

53     }

54     return 0;

55 }
View Code

 

 

 

你可能感兴趣的:(birt)