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,问 ...
随机推荐
- javascript-jquery对象的其他处理
一.对元素进行遍历操作 如果要遍历一个jquery对象,对其中每个匹配元素进行相应处理,那么可以使用each()方法. $("div").each(function(index,e ...
- 【UE4】GAMES101 图形学作业2:光栅化和深度缓存
总览 在上次作业中,虽然我们在屏幕上画出一个线框三角形,但这看起来并不是那么的有趣.所以这一次我们继续推进一步--在屏幕上画出一个实心三角形,换言之,栅格化一个三角形.上一次作业中,在视口变化之后,我 ...
- JVM:类加载与字节码技术-2
JVM:类加载与字节码技术-2 说明:这是看了 bilibili 上 黑马程序员 的课程 JVM完整教程 后做的笔记 内容 这部分内容在上一篇笔记中: 类文件结构 字节码指令 编译期处理 类加载阶段 ...
- Linux C语言链表你学会了吗?
链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用.链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节 ...
- UVM:6.2.3 sequencer 的grab 操作
转载:UVM:6.2.3 sequencer 的grab 操作_tingtang13的博客-CSDN博客 1.grab 比lock 优先级更高. 2.lock 是插到sequencer 仲裁队列的后面 ...
- Android 服务名称规则invalid service name 限制16字符以内
今天调试网络服务的时候为了区分,修改了原有服务名称,同时新增了两个服务. 系统运行的时候报错找不到对应的服务 init: no such service 'wpa_supplicant_common' ...
- heihei
adb shell screencap -p /sdcard/p1.pngadb pull /sdcard/p1.png c:\BaiduYunDownloadadb shell rm /sdcard ...
- linux 内核源代码情景分析——地址映射的全过程
linux 内核采用页式存储管理.虚拟地址空间划分成固定大小的"页面",由MMU在运行时将虚拟地址映射成某个物理内存页面中的地址.页式内存管理比段式内存管理有很多好处,但是由于In ...
- 聊了聊宏内核和微内核,并吹了一波 Linux
看这里!!!https://mp.weixin.qq.com/s?__biz=MzI0ODk2NDIyMQ==&mid=2247494048&idx=1&sn=cacfc6a4 ...
- (三)lamp环境搭建之编译安装php
1,PRC (People's republic of China) timezone中设置的时间为中国时间. 2,php的官方镜像源,使用linux时可以直接下载的 http://cn2.php.n ...