题目描述
给出一个长度为 n n n 的数列 {ai} 和一个长度为m 的数列 {bi} ,求 {ai}有多少个长度为 m 的连续子数列能与 {bi} 匹配。
两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当且仅当它们的和不小于 h。
样例
样例输入 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
《霍尔定理》:霍尔定理是判断二分图能否完美匹配的一个定理。
1.二分图两个点集a,b的点数必须相同。
2.对于a中任意大小为n的子集,b中可与该子集匹配的点的数量>=n。
霍尔定理是匈牙利算法的基础,看了一个讲霍尔定理的顺手写一下这题。
首先,将b从小到大排序,则每个ai可以匹配的序列为b[j…m],对于a选定的长度为m的连续子序列,可以递归证明满足条件当对于任意bi(1,2,3,…m),可以与其匹配a的子序列中的数字的个数ci>=i时,则可以达成完美匹配。
所以线段树维护一下ci即可,定长区间不断右移,从右边进入区间的在增加,从左边出去的减少,每个区间判断能否满足来统计答案。
区间修改是logm,而对于查询,只需要初始置b[i]=-i,则线段树查询区间[1,n]的最小值大于等于0即可满足条件。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=150005;
const int maxm=maxn*4;
const int mod=