CF338E Optimize!
https://www.luogu.com.cn/problem/CF338E
转换一手
令 b [ i ] = h − b [ i ] b[i]=h-b[i] b[i]=h−b[i],那么条件完美匹配条件变为排序后 a [ i ] > b [ i ] a[i]>b[i] a[i]>b[i],容易证明这是充要的
转换到这一步还是不太好做
考虑离散化后把
b
[
i
]
b[i]
b[i]设为
−
1
-1
−1,
a
[
i
]
a[i]
a[i]设为
1
1
1,
维护权值的前缀和,那么就要保证每个前缀和都
>
=
0
>=0
>=0,这个可以用线段树轻松实现
代码实现很简单
code:
#include<bits/stdc++.h>
#define N 300050
#define ls (rt << 1)
#define rs (rt << 1 | 1)
using namespace std;
int mi[N << 2], tg[N << 2];
void padd(int rt, int o) {
mi[rt] += o, tg[rt] += o;
}
void pushdown(int rt) {
if(tg[rt]) {
padd(ls, tg[rt]), padd(rs, tg[rt]);
tg[rt] = 0;
}
}
void update(int rt) {
mi[rt] = min(mi[ls], mi[rs]);
}
void add(int rt, int l, int r, int L, int R, int o) {
if(L <= l && r <= R) {padd(rt, o); return ;}
pushdown(rt);
int mid = (l + r) >> 1;
if(L <= mid) add(ls, l, mid, L, R, o);
if(R > mid) add(rs, mid + 1, r, L, R, o);
update(rt);
}
int n, m, H, lim, a[N], b[N], lss[N << 1];
int main() {
scanf("%d%d%d", &n, &m, &H);
for(int i = 1; i <= m; i ++) scanf("%d", &b[i]), b[i] = H - b[i], lss[++ lim] = b[i];
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]), lss[++ lim] = a[i];
sort(lss + 1, lss + 1 + lim);
lim = unique(lss + 1, lss + 1 + lim) - lss - 1;
for(int i = 1; i <= m; i ++) b[i] = lower_bound(lss + 1, lss + 1 + lim, b[i]) - lss;
for(int i = 1; i <= n; i ++) a[i] = lower_bound(lss + 1, lss + 1 + lim, a[i]) - lss;
for(int i = 1; i <= m; i ++) add(1, 1, lim, a[i], lim, -1), add(1, 1, lim, b[i], lim, 1);
int ans = 0;
ans += mi[1] >= 0;
for(int i = m + 1; i <= n; i ++) add(1, 1, lim, a[i - m], lim, 1), add(1, 1, lim, a[i], lim, -1), ans += mi[1] >= 0;
printf("%d", ans);
return 0;
}