思路:
二分
有以下两种构造,
分别二分取个最小。
代码:
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head ULL n, h; bool check(ULL t) { ULL res; if(t >= h) res = (1+t)*t/2 + t*(t-1)/2 - h*(h-1)/2; else res = (1+t)*t/2; if(res >= n) return true; else return false; } bool Check(ULL t) { ULL res; if(t >= h) res = (1+t)*t - h*(h-1)/2; else res = (1+t)*t/2; if(res >= n) return true; else return false; } int main() { scanf("%llu%llu", &n, &h); ULL l = 0, r = 2e9, m = (l+r) >> 1; while(l < r) { if(check(m)) r = m; else l = m+1; m = (l+r) >> 1; } ULL ans; if(m >= h) ans = 2*m - h; else ans = m; l = 0, r = 2e9, m = (l+r) >> 1; while(l < r) { if(Check(m)) r = m; else l = m+1; m = (l+r) >> 1; } if(m >= h) ans = min(ans, 2*m - h + 1); else ans = min(ans, m); printf("%llu ", ans); return 0; }