Codeforces 338E - Optimize!(Hall 定理+线段树)
首先 \(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 定理+线段树)的更多相关文章
- loj#6062. 「2017 山东一轮集训 Day2」Pair hall定理+线段树
题意:给出一个长度为 n的数列 a和一个长度为 m 的数列 b,求 a有多少个长度为 m的连续子数列能与 b匹配.两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当 ...
- BZOJ.3693.圆桌会议(Hall定理 线段树)
题目链接 先考虑链.题目相当于求是否存在完备匹配.那么由Hall定理,对于任意一个区间[L,R],都要满足[li,ri]完全在[L,R]中的ai之和sum小于等于总位置数,即R-L+1.(其实用不到H ...
- LOJ.6062.[2017山东一轮集训]Pair(Hall定理 线段树)
题目链接 首先Bi之间的大小关系没用,先对它排序,假设从小到大排 那么每个Ai所能匹配的Bi就是一个B[]的后缀 把一个B[]后缀的匹配看做一条边的覆盖,设Xi为Bi被覆盖的次数 容易想到 对于每个i ...
- BZOJ3693: 圆桌会议(Hall定理 线段树)
题意 题目链接 Sol 好的又是神仙题... 我的思路:对于区间分两种情况讨论,一种是完全包含,另一种是部分包含.第一种情况非常好判断,至于计算对于一个区间[l, r]的$\sum a[i]$就可以了 ...
- 模拟赛 怨灵退治 题解(Hall定理+线段树)
题意: 有 n 群怨灵排成一排,燐每秒钟会选择一段区间,消灭至多 k 只怨灵. 如果怨灵数量不足 k,则会消灭尽量多的怨灵. 燐作为一只有特点的猫,它选择的区间是不会相互包含的.它想要知道它每秒最多能 ...
- 【BZOJ2138】stone Hall定理+线段树
[BZOJ2138]stone Description 话说Nan在海边等人,预计还要等上M分钟.为了打发时间,他玩起了石子.Nan搬来了N堆石子,编号为1到N,每堆包含Ai颗石子.每1分钟,Nan会 ...
- BZOJ1135 LYZ(POI2009) Hall定理+线段树
做这个题之前首先要了解判定二分图有没有完备匹配的Hall定理: 那么根据Hell定理,如果任何一个X子集都能连大于等于|S|的Y子集就可以获得完备匹配,那么就是: 题目变成只要不满足上面这个条件就能得 ...
- ARC076 F Exhausted? Hall定理 + 线段树扫描线
---题面--- 题目大意: 有n个人,m个座位,每个人可以匹配的座位是[1, li] || [ri, m],可能有人不需要匹配座位(默认满足),问最少有多少人不能被满足. 题解: 首先可以看出这是一 ...
- codeforces Good bye 2016 E 线段树维护dp区间合并
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
随机推荐
- VS Code Just My Code Debugging
VS Code Just My Code Debugging VS Code for C++ doesn't support Just My Code Refer here: Add support ...
- [软工顶级理解组] 团队规划和任务拆解(Beta)
目录 需求再分析 功能增减 管理改进 任务分解 人员管理 需求再分析 在Alpha阶段,我们的产品得到了用户的广泛好评,但是还是存在一些问题. 登录不稳定,登录速度慢等问题:这是北航VPN本身的不稳定 ...
- [对对子队]会议记录5.19(Scrum Meeting6)
今天已完成的工作 吴昭邦 工作内容:搭建第9关 相关issue:搭建关卡7.8.9 相关签入:feat: 第9关能够通过 何瑞 工作内容:搭建第9关 相关issue:搭建关卡7.8 ...
- [no code][scrum meeting] Alpha 3
项目 内容 会议时间 2020-04-07 会议主题 技术规格说明书review 会议时长 1h30min 参会人员 产品经理+后端技术组长(伦泽标)+OCR竞品调研成员(叶开辉)+架构文档负责(黎正 ...
- git为单独的仓库设置提交的用户名
在我们平时的学习中可能有这么一种需求,在公司进行开发的时候,一般会参与多个项目的开发,而项目提交代码时,一般请求情况下提供的用户都是同一个,而我们为了方便可能会使用全局进行git 用户名的配置.但是空 ...
- RF射频传输,原理介绍,三分钟看懂!发射功率、接收灵敏度详解!
射频是什么? 官方说法:RF,Radio Frequency. (不懂的人,看了还是不懂,不过对于物联网行业的开发工程师.产品经理和项目经理,还是有需要对射频有个基础了解的.) 燚智能解读: 两个人, ...
- python画图的工具及网站
①Gallery - Matplotlib 3.4.3 documentation 学会模仿并超越 ②Examples - Apache ECharts js网页端动态展示 ③WEB色見本 原色大辞典 ...
- IM服务器:我的千万级在线聊天服务器集群
一.服务器特点 01.傻瓜式部署,一键式启动: 02.单机支持10万以上在线用户聊天(8G内存,如果内存足够大,并发量可超过10万): 03.支持服务器集群,集群间高内聚.低耦合,可动态横向扩展IM服 ...
- Des加密解密(公共方法)
1 public class Des 2 { 3 public static string Encrypt(string message, string key) 4 { 5 DES des = ne ...
- VIVADO 2017.4配置MIG IP注意事项
1.2GB的single rank SODIMMs配置pin还是和以前一样没有问题: 2.8GB SODIMMs配置pin需要注意4点: (1).所有的DDR3引脚都需要在连续的BANK上,例如Z71 ...