#define int long long constint N = 2e5 + 50; int a[N]; int le[N], ri[N]; int lg2[N], f[N][20]; int n, k; intquery(int l, int r) { int k = lg2[r - l + 1]; returnmax(f[l][k], f[r - (1 << k) + 1][k]); }
boolcheck(int x) { int tot = 0; for (int i = 1; i <= n; ++i) { int l = le[i] - 1, r = i + 1; int L, R; while (l + 1 < r) { int mid = (l + r) >> 1; if (query(mid, i) < x - a[i])//mid-min r = mid; else l = mid; } L = r; l = i - 1, r = ri[i] + 1; while (l + 1 < r) { int mid = (l + r) >> 1; if (query(i, mid) < x - a[i]) l = mid; else r = mid; } R = l; tot += (i - le[i] + 1) * (ri[i] - i + 1) - (i - L + 1) * (R - i + 1); } return tot >= k; }
voidsolve() {
cin >> n >> k; for (int i = 1; i <= n; ++i) cin >> a[i]; a[0] = -inf, a[n + 1] = -inf; stack<int> stk;
for (int i = 2; i <= n; ++i) lg2[i] = lg2[i >> 1] + 1; for (int i = 1; i <= n; ++i) f[i][0] = a[i]; for (int j = 1; j <= lg2[n]; ++j) // 初始化 { for (int i = 1; i + (1 << (j - 1)) <= n; ++i) { f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]); } }
for (int i = n + 1; i >= 0; --i) {
while (!stk.empty() && a[stk.top()] > a[i]) // 此处可以更改比较关系 { le[stk.top()] = i + 1; stk.pop(); } stk.push(i); } while (!stk.empty()) stk.pop(); for (int i = 0; i <= n + 1; ++i) {
while (!stk.empty() && a[stk.top()] >= a[i]) // 此处可以更改比较关系 { ri[stk.top()] = i - 1; stk.pop(); } stk.push(i); }
int l = 0, r = inf; while (l + 1 < r) { int mid = l + r >> 1; if (check(mid)) // 二分答案 if(check(mid)) l = mid; // 最小化 else r = mid; } cout << l << endl; }