使用分治法
#include <stdio.h>
#include <inttypes.h>
#include <algorithm>
#include <functional>
using namespace std;
enum
{
MAXN = 200001,
};
int n;
int64_t a[MAXN], b[MAXN], s, cnt, sum[MAXN], mn[MAXN];
void calc_sum_mn(int le, int ri)
{
int mid = (le + ri) / 2, i = mid;
sum[i] = b[i];
mn[i] = a[i];
while (--i >= le)
{
sum[i] = b[i] + sum[i + 1];
mn[i] = min(a[i], mn[i + 1]);
}
i = mid + 1;
sum[i] = b[i];
mn[i] = a[i];
while (++i <= ri)
{
sum[i] = b[i] + sum[i - 1];
mn[i] = min(a[i], mn[i - 1]);
}
}
void work(int le, int ri)
{
if (le == ri)
{
cnt += (a[le] + b[le] <= s);
return;
}
int mid = (le + ri) / 2;
work(le, mid);
work(mid + 1, ri);
calc_sum_mn(le, ri);
/* 最小值在左半边 */
for (int i = mid, p = mid; i >= le; i--)
{
while (++p <= ri && mn[p] >= mn[i]) {}
if (--p == mid) continue;
int64_t* q = upper_bound(sum + mid + 1, sum + p + 1, s - sum[i] - mn[i]);
cnt += int64_t(q - (sum + mid + 1));
}
/* 最小值在右半边 */
for (int j = mid + 1, p = mid + 1; j <= ri; j++)
{
while (--p >= le && mn[p] >= mn[j]) {}
if (++p == mid + 1) continue;
int64_t* q = lower_bound(sum + p, sum + mid + 1, s - sum[j] - mn[j], greater<int64_t>());
cnt += int64_t(sum + mid + 1 - q);
}
}
int main(void)
{
(void)scanf("%d%" SCNd64, &n, &s);
for (int i = 0; i < n; i++) (void)scanf("%" SCNd64, &a[i]);
for (int i = 0; i < n; i++) (void)scanf("%" SCNd64, &b[i]);
work(0, n - 1);
printf("%" PRId64, cnt);
return 0;
}