Problem Link
Yukari’s Birthday
非常简单的二分题,给你一个数 n 让找
r,k
s,t
∑ri=1ki==n||n−1
,让你找满足条件的最小化
r∗k
多解就找最小的
r
分析
很简单的二分,枚举
用快速冪的时候一定注意范围溢出,找了很久的一个bug。
AC code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include <set>
#define fi first
#define se second
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
LL n;
const int maxn = 1e5+10;
PII ans;
LL power(LL x,LL n){
LL res = 1;
while (n) {
if(n%2)res*=x;
x*=x;
n>>=1;
}
return res;
}
void solve(){
LL ans_v = n-1;
ans.fi = 1;ans.se = n-1;
for(LL r = 2 ; r<=41 ; ++r){
LL left = 2 ; LL right = (LL)pow(n,1.0/r);
while (right>=left) {
LL mid = (right+left)>>1;
//std::cout << "power " << power(mid,r)<<endl;
LL sum = (mid-power(mid,r+1))/(1-mid);
//std::cout << sum << '\n';
if(sum == n || sum == n-1){
//std::cout << r << " "<<mid<< endl;
if(ans_v>r*mid){
ans_v = r*mid;
ans.fi = r;ans.se = mid;
}
break;
}
if(sum<n)left = mid+1;
else right = mid-1;
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
while (cin>>n) {
solve();
std::cout << ans.fi << " "<<ans.se<<endl;
//printf("%I64d %I64d\n",ans.fi,ans.se );
}
return 0;
}