题目
代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
int n;
LL C(int a, int b) //计算C(a,b)
{
LL res = 1;
for(int i = a, j = 1; j <= b; i --, j ++)
{
res = res * i / j;
if(res > n)
return res; // 大于n已无意义,且防止爆LL
}
return res;
}
bool check(int k)
{
// 二分该斜行,找到大于等于该值的第一个数
// 左边界2k,右边界为max(l, n)取二者最大,避免右边界小于左边界
int l = 2 * k, r = max(n,l);
while(l < r)
{
int mid = l + r >> 1;
if(C(mid, k) >= n) r = mid;
else l = mid + 1;
}
if(C(r, k) != n)
return false;
cout << 1ll*(r + 1) * r / 2 + k + 1 << endl;
return true;
}
int main()
{
cin >> n;
// 从第16斜行枚举
for(int i = 16; ; i--)
if(check(i))
break;
return 0;
}
时间复杂度
:
O
(
16
l
o
g
n
)
O(16logn)
O(16logn)