行了我快崩溃了
chat ban
这题二分就能过,各位加油
对于某一次二分得到的层 m i d mid mid,分类讨论其总符号数:
若 m i d < N mid<N mid<N,则直接使用等差数列求和公式: ( 1 + m i d ) × m i d ÷ 2 (1+mid)×mid÷2 (1+mid)×mid÷2
否则分两部分:第一部分是从 1 1 1 到 n n n 的和,第二部分是从 n − 1 n−1 n−1 到 n − 1 − ( i − n ) + 1 n−1−(i−n)+1 n−1−(i−n)+1 的和,然后将两部分相加即可。
ACcode:
#include <iostream> // 基本入出力ストリーム
#include <algorithm> // 一般的なアルゴリズム(ソート、ルックアップ、やり直し、二分ルックアップなど)
#include <vector> // 動的配列(スペースが足りないと自動的に拡張されます)
#include <queue> // スタック(先に入って先に出ます)
#include <stack> // スタック(先に入ってから出ます)
#include <set> // 集合(反復しない順序)です
#include <map> // キー値対コンテナ(マッピング)
#include <list> // 両方向リスト
#include <math.h> // すうがくかんすう
#include <functional> // 通用的函数绑定和调用机制一般的なバインディングと呼び出しの仕組み
#define endl '\n'
#define pii pair<int, int>
#define pdd pair<double, double>
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
using namespace std;
const int inf = 1e9 + 7;
const int mod = 998244353;
const int N = 2e5 + 10, M = N << 1;
typedef long long ll;
void solve() {
ll k, x;
cin >> k >> x;
if(k * k <= x) {
cout << 2 * k - 1 << endl;
} else {
ll l = 0, r = 2 * k - 1, ans = 2 * k - 1;
while(l <= r) {
ll mid = (l + r) / 2;
ll st = 0;//当前个数
if(mid <= k) st = mid * (mid + 1) / 2;
else {
ll p = 2 * k - 1 - mid;
st = k * k - p *(p + 1) / 2;
}
if(st >= x) ans = mid, r = mid - 1;
else l = mid + 1;
}
cout << ans << endl;
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--) solve();
}
已通过