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
",rr,kk);
53     }
54     return 0;
55 }
View Code
原文地址:https://www.cnblogs.com/xin-hua/p/3283061.html