题面传送门

首先 \(b_i\) 的顺序肯定不会影响匹配,故我们可以直接将 \(b\) 数组从小到大排个序。

我们考虑分析一下什么样的长度为 \(m\) 的数组 \(a_1,a_2,\dots,a_m\) 能和 \(b\) 数组形成匹配。考虑对于 \(i,j\in [1,m]\),若 \(a_i+b_j\geq h\),就在 \(i,j\) 之间连边,那么形成的图必然是一张二分图,我们只需检验这张二分图是否存在完美匹配即可。

这时候就要用到一个叫做 Hall 定理的科技了。Hall 定理说的是这样一件事,对于二分图 \(G=(V_1,V_2,E)\),定义函数 \(f(V)(V\in V_1)\) 为与点集 \(V\) 中的点相连的点的(右部点)集合。那么二部图 \(G\) 有完美匹配的充要条件是 \(\forall V\subseteq V_1,|f(V)|\geq |V|\)

必要性:这个就比较显然了吧。。。记对于节点 \(u\),记 \(mch(u)\) 为与 \(u\) 匹配的节点。那么我们构造集合 \(V'=\{v|v=mch(u),u\in V\}\),那么 \(|V'|=|V|\),而根据 \(V'\) 的构造方式可知 \(\forall v\in V'\) 至少存在一个 \(u\in V\) 满足 \(u,v\) 间有边,故 \(V'\subseteq f(V)\),于是有 \(|V|=|V'|\leq f(V)\),得证。

充分性:这个就没那么显然了。考虑反证法,假设二分图 \(G\) 不存在完美匹配但满足 Hall 定理。那么我们构造出 \(G\) 的一种最大匹配,其中必存在某个非匹配点,假设其为 \(A\)。根据 Hall 定理 \(A\) 必定与另一边某个点相连,设其为 \(B\)。而 \(B\) 必须为匹配点,否则 \(A,B\) 就能形成新的匹配,不满足最大匹配的条件了,设 \(C\) 为与 \(B\) 相匹配的点。再对集合 \(\{A,C\}\) 使用 Hall 定理可知,\(\{A,C\}\) 除 \(B\) 外必与其它某个点相连,设其为 \(D\)。\(D\) 也必须为匹配点,否则根据之前的证明过程可知它不能与 \(A\) 相连,否则 \(A,D\) 能形成新的匹配,故它只能与 \(C\) 相连,而若它与 \(C\) 相连,那么将匹配边 \((B,C)\) 换为 \((A,B),(C,D)\) 可让匹配个数多 \(1\),不满足最大匹配的条件,故 \(D\) 一定与某个点 \(E\) 匹配。再对集合 \(\{A,C,E\}\) 使用 Hall 定理可得还存在某个点 \(F\) 与这三个点都相连且为匹配点。如此一直进行下去可进行无限轮,而点集的大小是有限的,矛盾!

回到本题来,设 \(c(j)\) 为排好序后与 \(b_j\) 能匹配的 \(a_i\) 的个数。由于我们 \(b\) 数组是有序的,那么就有 \(\forall i<j,c(i)<c(j)\),也就是说对于 \(i<j\),所有能与 \(b_i\) 匹配的 \(a_k\) 都能和 \(b_j\) 匹配。而根据 Hall 定理,原图存在完美匹配的充要条件是 \(\forall V\subseteq V_1,|f(V)|\geq |V|\),故对于大小为 \(k\) 的集合 \(S=\{b_{i_1},b_{i_2},\dots,b_{i_s}\}\) 必有 \(\max(f(i_1),f(i_2),\dots,f_(i_s))\geq k\),而显然所有这样的集合中 \(\max(f(i_1),f(i_2),\dots,f_(i_s))\) 的最小值为 \(f(k)\)。故连边形成的图存在完美匹配等价于 \(\forall i,f(i)\geq i\)。

最后考虑加上 \(a\) 数组之后怎样处理,考虑建一棵线段树维护 \(f(i)\)。显然对于每个 \(a_i\) 可二分找出最小的满足 \(b_j\geq h-a_i\) 的 \(j\) 并在线段树 \([j,m]\) 的位置整体加 \(1\)。那么怎么知道 \(\forall i,f(i)\geq i\) 是否成立呢?我们就初始在线段树上每个位置赋上 \(-i\) 并检查全局最小值是否 \(\geq 0\) 就行了。

时间复杂度线对。

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define ffe(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=1;
while(!isdigit(c)){if(c=='-') neg=-1;c=getchar();}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
x*=neg;
}
const int MAXN=1.5e5;
const int INF=0x3f3f3f3f;
int n,m,k,a[MAXN+5],b[MAXN+5],pos[MAXN+5];
struct node{int l,r,mn,lz;} s[MAXN*4+5];
void build(int k,int l,int r){
s[k].l=l;s[k].r=r;if(l==r){s[k].mn=-l;return;}
int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);
s[k].mn=min(s[k<<1].mn,s[k<<1|1].mn);
}
void pushdown(int k){
if(s[k].lz!=0){
s[k<<1].mn+=s[k].lz;s[k<<1].lz+=s[k].lz;
s[k<<1|1].mn+=s[k].lz;s[k<<1|1].lz+=s[k].lz;
s[k].lz=0;
}
}
void modify(int k,int l,int r,int x){
if(l>r) return;
if(l<=s[k].l&&s[k].r<=r){s[k].mn+=x;s[k].lz+=x;return;}
pushdown(k);int mid=(s[k].l+s[k].r)>>1;
if(r<=mid) modify(k<<1,l,r,x);
else if(l>mid) modify(k<<1|1,l,r,x);
else modify(k<<1,l,mid,x),modify(k<<1|1,mid+1,r,x);
s[k].mn=min(s[k<<1].mn,s[k<<1|1].mn);
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++) scanf("%d",&a[i]);
a[0]=-INF;sort(a+1,a+m+1);build(1,1,m);
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
pos[i]=lower_bound(a,a+m+1,k-b[i])-a;
// printf("%d\n",pos[i]);
}
for(int i=1;i<m;i++) modify(1,pos[i],m,1);
int ans=0;
for(int i=m;i<=n;i++){
modify(1,pos[i],m,1);
// printf("%d\n",s[1].mn);
if(s[1].mn>=0) ans++;
modify(1,pos[i-m+1],m,-1);
} printf("%d\n",ans);
return 0;
}

Codeforces 338E - Optimize!(Hall 定理+线段树)的更多相关文章

  1. loj#6062. 「2017 山东一轮集训 Day2」Pair hall定理+线段树

    题意:给出一个长度为 n的数列 a和一个长度为 m 的数列 b,求 a有多少个长度为 m的连续子数列能与 b匹配.两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当 ...

  2. BZOJ.3693.圆桌会议(Hall定理 线段树)

    题目链接 先考虑链.题目相当于求是否存在完备匹配.那么由Hall定理,对于任意一个区间[L,R],都要满足[li,ri]完全在[L,R]中的ai之和sum小于等于总位置数,即R-L+1.(其实用不到H ...

  3. LOJ.6062.[2017山东一轮集训]Pair(Hall定理 线段树)

    题目链接 首先Bi之间的大小关系没用,先对它排序,假设从小到大排 那么每个Ai所能匹配的Bi就是一个B[]的后缀 把一个B[]后缀的匹配看做一条边的覆盖,设Xi为Bi被覆盖的次数 容易想到 对于每个i ...

  4. BZOJ3693: 圆桌会议(Hall定理 线段树)

    题意 题目链接 Sol 好的又是神仙题... 我的思路:对于区间分两种情况讨论,一种是完全包含,另一种是部分包含.第一种情况非常好判断,至于计算对于一个区间[l, r]的$\sum a[i]$就可以了 ...

  5. 模拟赛 怨灵退治 题解(Hall定理+线段树)

    题意: 有 n 群怨灵排成一排,燐每秒钟会选择一段区间,消灭至多 k 只怨灵. 如果怨灵数量不足 k,则会消灭尽量多的怨灵. 燐作为一只有特点的猫,它选择的区间是不会相互包含的.它想要知道它每秒最多能 ...

  6. 【BZOJ2138】stone Hall定理+线段树

    [BZOJ2138]stone Description 话说Nan在海边等人,预计还要等上M分钟.为了打发时间,他玩起了石子.Nan搬来了N堆石子,编号为1到N,每堆包含Ai颗石子.每1分钟,Nan会 ...

  7. BZOJ1135 LYZ(POI2009) Hall定理+线段树

    做这个题之前首先要了解判定二分图有没有完备匹配的Hall定理: 那么根据Hell定理,如果任何一个X子集都能连大于等于|S|的Y子集就可以获得完备匹配,那么就是: 题目变成只要不满足上面这个条件就能得 ...

  8. ARC076 F Exhausted? Hall定理 + 线段树扫描线

    ---题面--- 题目大意: 有n个人,m个座位,每个人可以匹配的座位是[1, li] || [ri, m],可能有人不需要匹配座位(默认满足),问最少有多少人不能被满足. 题解: 首先可以看出这是一 ...

  9. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

随机推荐

  1. 初学python-day6 for循环和流程控制(已更新循环做三角形图形!!)

    for循环 1.格式 for    变量    in   集合: 循环体 2.概述 当程序执行for循环,按顺序从集合中获取元素变量保存当前循环得到的值,再去执行循环体.当集合中数据都被取完,则此刻跳 ...

  2. javascript-jquery介绍

    jquery优势 1.轻量级 2.强大的选择器 3.出色的DOM封装 4.可靠的事件处理机制 5.完善的Ajax 6.不污染顶级变量 7.出色的浏览器兼容 8.链式操作方式 9.隐式迭代 10.行为层 ...

  3. SharkCTF2021 The_nature_of_the_human

    (信安数基的quiz1写不出来 来这放题解泄愤) crypto类题. 题面 其加密的大致过程是,对明文flag中的逐个字符,随机使用三种加密方式: 第一种,对该字符进行sha256加密后以16进制形式 ...

  4. 【Python从入门到精通】(二)怎么运行Python呢?有哪些好的开发工具(PyCharm)

    您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦. 这是Pyhon系列文章的第二篇,本文主要介绍如何运行Python程序以及安装PyCharm开发工具. 干货满满,建议收藏,需要用到时常看看. 小伙 ...

  5. MySQL:基础语法-4

    MySQL:基础语法-4 记录一下 MySQL 基础的一些语法,便于查询,该部分内容主要是参考:bilibili 上 黑马程序员 的课程而做的笔记,由于时间有点久了,课程地址忘记了 上文MySQL:基 ...

  6. springcloud整合seata

    springcloud整合seata 一.背景 二.项目结构 三.实现功能: 四.项目使用到的技术 五.整合步骤 1.引入spring-cloud-starter-alibaba-seata jar包 ...

  7. CODING 助力江苏高速信息实现组织敏捷与研发敏捷,领跑智慧交通新基建

    疫情之下的高速公路管控重任 江苏高速公路信息工程有限公司(以下简称:江苏高速信息)成立于 2002 年,是江苏交通控股旗下,专业从事高速公路领域机电系统集成.智能交通软硬件研发.大数据分析运营的高新技 ...

  8. 常用Java API:大数类

    摘要 java中的基础数据类型能存储的最大的二进制数是 2 ^ 63 - 1, 对应的十进制数是9223372036854775807,也就是说只要运算过程中会超过这个数,就会造成数据溢出,从而造成错 ...

  9. cf18B Platforms(仔细谨慎题)

    题意: In one one-dimensional world there are n platforms. Platform with index k (platforms are numbere ...

  10. NOIP模拟92(多校25)

    前言 所以说这次是 HZOI 多校联测巅峰????(题目,数据过水??) T1 石子合并 解题思路 签到题. 发现我们可以给每个数字附一个正负号,每个数字的贡献就是它本身乘上这个符号. 发现至少应该有 ...