タイトル説明
所与の長さ の列の数 との長さ の列の数は 、検索 長の数は 、サブシリーズと連続することができる 試合。
二つの列が一致することができ、かつスキームがある場合、2の列の数がオフペアリングすることができる、2つの数字があればペアリングすることができ、それらは唯一の場合よりも小さくない場合にのみ 。
入力形式
3つの数字の最初の行 。
第二行は有し 番号 。
第3段目は、有している 数字 。
出力フォーマット
デジタル出力は、 長さの数は、 サブシリーズと連続することができる 試合。
サンプル
サンプル入力1
5 2 10
5 3
1 8 5 5 7
サンプル出力1
2
サンプル入力2
2 2 6
2 3
3 4
サンプル出力2
1
サンプル入力3
4 2 10
5 5
9 3 8 9
サンプル出力3
1
データ範囲とヒント
以下のための データ ;
のための データ ;
のための データ ;
のため のデータ 。
溶液:
式は、ホール定理によって導入することができます
ペアの間隔
合計で、私は、双方向の接続点の数を表し、
各合計のために、私は合計を満たしている場合、私は> =私は完璧に一致することができます
コード:
#include <bits/stdc++.h> #define REP(i, a, b) for (int i = a; i <= b; ++i) typedef long long ll; using namespace std; void File() { freopen("loj6062.in", "r", stdin); freopen("loj6062.out", "w", stdout); } const int maxn = 1.5e5 + 10; int n, m, h, a[maxn], b[maxn], ans; struct Segment_Tree { #define mid ((l + r) >> 1) #define lc rt << 1 #define rc rt << 1 | 1 #define lson lc, l, mid #define rson rc, mid + 1, r int Min[maxn << 2], tag[maxn << 2]; void pushdown(int rt) { Min[lc] += tag[rt]; tag[lc] += tag[rt]; Min[rc] += tag[rt]; tag[rc] += tag[rt]; tag[rt] = 0; } void build(int rt, int l, int r) { if (l == r) Min[rt] = -l; else { build(lson); build(rson); Min[rt] = min(Min[lc], Min[rc]); } } void modify(int rt, int l, int r, int L, int R, int x) { if (L > R) return; if (L <= l && r <= R) { Min[rt] += x; tag[rt] += x; } else { if (tag[rt]) pushdown(rt); if (L <= mid) modify(lson, L, R, x); if (R >= mid + 1) modify(rson, L, R, x); Min[rt] = min(Min[lc], Min[rc]); } } } T; void init() { scanf("%d%d%d", &n, &m, &h); REP(i, 1, m) scanf("%d", &b[i]); sort(b + 1, b + m + 1); REP(i, 1, n) { scanf("%d", &a[i]); a[i] = lower_bound(b + 1, b + m + 1, h - a[i]) - b; } T.build(1, 1, m); REP(i, 1, m - 1) T.modify(1, 1, m, a[i], m, 1); } int main() { // File(); init(); REP(i, m, n) { T.modify(1, 1, m, a[i], m, 1); ans += (T.Min[1] >= 0); T.modify(1, 1, m, a[i - m + 1], m, -1); } printf("%d\n", ans); return 0; }