CF1042D Petya and Array 题解
比较典的一个题。
题意:给定 $\{a_n\},t$,求 $\sum\limits_{l=1}^n\sum\limits_{r=l}^n[\sum\limits_{i=l}^ra_i<t]$。
思路
令 $s_x=\sum\limits_{i=1}^xa_i$,则原式等于 $\sum\limits_{l=1}^n\sum\limits_{r=l}^n[s_r-s_{l-1}<t]$。
考虑枚举 $r$,统计 $l-1<r\bigwedge s_{l-1}>s_r-t$ 的 $l-1$ 的个数。
发现是个二维偏序,用权值树状数组维护之,复杂度 $O(n\log n)$。
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define F(x) v[m++] = x
#define H(x) lower_bound(v, v + m, x) - v + 1
using namespace std;
inline long long R()
{
long long r = 0;bool b = 0;char c = getchar();
while(!isdigit(c)) b = c == '-', c = getchar();
while(isdigit(c)) r = r * 10 + c - '0', c = getchar();
return b ? -r : r;
}
int n, m = 1, c[400050];long long t, q, a[200050], v[400050];
void C(int x) {for(;x <= m;x += x & -x) ++c[x];}
int Q(int x)
{
int q = 0, y = m;for(--x;y > x;y &= y - 1) q += c[y];
for(;x > y;x &= x - 1) q -= c[x];return q;
}
int main()
{
n = R();t = R();for(int i = 1;i <= n;++i)
F(a[i] = a[i - 1] + R()), F(a[i] - t + 1);
sort(v, v + m);m = unique(v, v + m) - v;C(H(0));
for(int i = 1;i <= n;++i) q += Q(H(a[i] - t + 1)), C(H(a[i]));
return printf("%lld", q), 0;
}