Solution
设
ai
的前缀和为
Si
。满足条件的区间
[l,r]
相当于
Sr−Slr−l≥k
,整理一下就是
sr−kr≥sl−kl
。
设
fi=si−ki
,题目求得就是
fl≤fr,l<r
的点对
(l,r)
个数。
树状数组。
哦。。其实单调栈就行了吧
#include <bits/stdc++.h>
using namespace std;
const int N = 202020;
typedef long long ll;
inline char get(void) {
static char buf[100000], *S = buf, *T = buf;
if (S == T) {
T = (S = buf) + fread(buf, 1, 100000, stdin);
if (S == T) return EOF;
}
return *S++;
}
template<typename T>
inline void read(T &x) {
static char c; x = 0; int sgn = 0;
for (c = get(); c < '0' || c > '9'; c = get()) if (c == '-') sgn = 1;
for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0';
if (sgn) x = -x;
}
int a[N], g[N], c[N];
ll s[N], f[N], mp[N];
ll ans;
int n, m, k;
inline void Add(int x) {
for (; x <= m; x += x & -x) ++c[x];
}
inline int Sum(int x) {
int sum = 0;
for (; x; x -= x & -x) sum += c[x];
return sum;
}
int main(void) {
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
read(n); read(k);
for (int i = 1; i <= n; i++) {
read(a[i]); s[i] = s[i - 1] + a[i];
}
for (int i = 0; i <= n; i++)
mp[i] = f[i] = s[i] - (ll)k * i;
sort(mp, mp + n + 1);
m = unique(mp, mp + n + 1) - mp;
for (int i = 0; i <= n; i++)
g[i] = lower_bound(mp, mp + m, f[i]) - mp + 1;
for (int i = 0; i <= n; i++) {
ans += Sum(g[i]); Add(g[i]);
}
cout << ans << endl;
return 0;
}