救救孩子把,调了一上午了
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
int n, k, a[N], b[N], l[N], r[N], sum[N], res;
stack<int> s;
signed main() {
cin >> n >> k;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i], sum[i] = sum[i - 1] + b[i];
a[0] = a[n + 1] = 0;
for (int i = 1; i <= n; i++) {
if (s.size() && a[s.top()] >= a[i]) s.pop();
if (s.size()) l[i] = s.top();
else l[i] = i - 1;
s.push(i);
}
while (s.size()) s.pop();
for (int i = n; i; i--) {
if (s.size() && a[s.top()] >= a[i]) s.pop();
if (s.size()) r[i] = s.top();
else r[i] = i + 1;
s.push(i);
}
for (int i = 1; i <= n; i++) {
int ls = l[i] + 1, rs = r[i] - 1;
if (i - ls < rs - i) {
for (int j = ls; j <= i; j++) {
int lq = i, rq = rs;
while (lq < rq) {
int mid = (lq + rq + 1) >> 1;
if (sum[mid] - sum[j - 1] + a[i] <= k) lq = mid;
else rq = mid - 1;
}
res += (lq - i + 1);
}
}
else {
for (int j = i; j <= rs; j++) {
int lq = ls, rq = i;
while (lq < rq) {
int mid = (lq + rq) >> 1;
if (sum[j] - sum[mid - 1] + a[i] <= k) rq = mid;
else lq = mid + 1;
}
res += (i - lq + 1);
}
}
}
cout << res << endl;
}
做法是从 min 入手,假设 ai=min{al,al+1,....,ar},左边右边找到 l,r 的边界,再来二分