hall定理大概是匈牙利的理论基础吧

hall定理的内容:二分图\(G\)的的左部点点集为\(\rm X\),右部点点集为\(\rm Y\),设\(|\rm X|\leq |Y|\),则二分图\(G\)存在完美匹配,即匹配个数为\(|\rm X|\)当且仅当,对于\(\rm X\)的任一子集\(\rm X'\),满足\(|\rm X'|\leq |\rm Nb(X')|\),\(\rm Nb(X')\)为\(\rm X'\)的邻居点集

必要性显然,考虑证明其充分性。

使用反证法,对于一张满足hall定理的二分图,设其不存在完美匹配,我们找到\(\rm X\)中一个不在最大匹配中的点,由于满足hall定理这个点一定连向了\(\rm Y\)中某些点,又因为该点不在最大匹配中,那么其连向的点都已经跟其他点匹配;我们再把跟这些点匹配的点考虑进来,根据hall定理,我们还能找到一些跟这些点相连但已经匹配的点,再把跟这些匹配的点考虑进来;最后不难推出,不存在满足hall定理但不存在完美匹配的二分图。

hall定理还有一条推论:二分图\(G\)的最大匹配为\(|\rm X|-\max(|X'|-|Nb(X')|)\),这条推论对于我们求二分图最大匹配有一定启发

对于这道题,可以显然的构造一个二分图模型,答案就是n-最大匹配;

直接建图是不可取的,考虑使用上面的推论,我们需要找到一个\(\rm X'\)使得\(\rm |X'|-|Nb(X')|\)即可

对于第\(i\)个人他可以连边的区间是\([1,l_i]\cup [r_i,m]\),由于\(\rm Nb(X)\)本质上是点集的并,而这样不是很好考虑;于是我们做一个简单的转化,我们求一下不能连边的区间的交,对全集取一个补集得到的就是区间的并

于是我们的目标是找到一个集合\(S\),最大化

\[|S|-(m-|\cap_{i\in S}(l_i,r_i)|)=|S|+|\cap_{i\in S}(l_i,r_i)|-m
\]

先来考虑没有交的情况,那么只需要让\(|S|\)最大,于是答案就是\(n-m\)

再来考虑有交的情况,之后对于当前的一个区间\((l_i,r_i)\)我们考虑交的左端点为\(l_i\)的时候的答案是多少,那么交为\((l_i,k)\)的时候的答案就是\(k-l_i+\sum [r_j\geq k][l_j\leq l_i]\);于是把区间排序之后线段树+扫描线维护即可。

代码

#include<bits/stdc++.h>
#define re register
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=2e5+5;
struct Seg{int x,y;}a[maxn];
int n,m,ans;
inline int cmp(const Seg A,const Seg B) {return A.x==B.x?A.y>B.y:A.x<B.x;}
int l[maxn<<2],r[maxn<<2],tag[maxn<<2],mx[maxn<<2];
inline int max(int a,int b) {return a>b?a:b;}
inline void add(int i,int v) {tag[i]+=v,mx[i]+=v;}
inline void pushup(int i) {mx[i]=max(mx[i<<1],mx[i<<1|1]);}
void build(int x,int y,int i) {
l[i]=x,r[i]=y;tag[i]=0;if(x==y){mx[i]=x;return;}
int mid=x+y>>1;build(x,mid,i<<1),build(mid+1,y,i<<1|1);pushup(i);
}
inline void pushdown(int i) {
if(!tag[i]) return;
add(i<<1,tag[i]),add(i<<1|1,tag[i]);tag[i]=0;
}
void change(int x,int y,int v,int i) {
if(x<=l[i]&&y>=r[i]) {add(i,v);return;}
int mid=l[i]+r[i]>>1;pushdown(i);
if(x<=mid) change(x,y,v,i<<1);
if(y>mid) change(x,y,v,i<<1|1);
pushup(i);
}
int query(int x,int y,int i) {
if(x<=l[i]&&y>=r[i]) return mx[i];
int mid=l[i]+r[i]>>1;pushdown(i);
if(y<=mid) return query(x,y,i<<1);
if(x>mid) return query(x,y,i<<1|1);
return max(query(x,y,i<<1),query(x,y,i<<1|1));
}
int main() {
scanf("%d%d",&n,&m);
for(re int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
std::sort(a+1,a+n+1,cmp);int nl=0,nr=m+1;
for(re int i=1;i<=n;i++) nl=max(nl,a[i].x),nr=min(nr,a[i].y);
ans=n+(nl<nr?nr-nl-1:0);
build(0,m+1,1);
for(re int i=1;i<=n;i++) {
int nw=query(a[i].x+1,a[i].y,1);
ans=max(ans,nw-a[i].x);
change(0,a[i].y,1,1);
}
printf("%d\n",ans>m?ans-m:0);return 0;
}

【ARC076F】 Exhausted的更多相关文章

  1. 【POJ1417】【带标记并查集+DP】True Liars

    Description After having drifted about in a small boat for a couple of days, Akira Crusoe Maeda was ...

  2. 【USACO09FEB】 庙会班车 Fair Shuttle 贪心+线段树

    Although Farmer John has no problems walking around the fair to collect prizes or see the shows, his ...

  3. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  4. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  5. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  6. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  7. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  8. Python高手之路【三】python基础之函数

    基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...

  9. Python高手之路【一】初识python

    Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...

随机推荐

  1. .ef core 多对对关系的关联方法

    最近在用.net core 重构博客,在使用ef core连表查询时,遇到了一些问题.记录一下. 关系:一个博客可以有多个标签,一个标签可以属于多个博客,博客和标签之间存在多对多的关系 下面是实体代码 ...

  2. ios-实现ARC与MRC混编

    选择target -> build phases -> compile sources -> 用ARC的文件将compiler flags设置为:-fobjc-arc,用MRC的文件 ...

  3. Djano中static和media文件路径的设置

    对于常用的css.js.image和常用的工具类在django项目中要设置一个全局的路径,对所有的app都可以访问到这个路径下的文件 1在django项目的setting文件中设置对应的static和 ...

  4. 「校内训练 2019-04-23」越野赛车问题 动态dp+树的直径

    题目传送门 http://192.168.21.187/problem/1236 http://47.100.137.146/problem/1236 题解 题目中要求的显然是那个状态下的直径嘛. 所 ...

  5. [BZOJ2341][Shoi2011]双倍回文 manacher+std::set

    题目链接 发现双倍回文串一定是中心是#的回文串. 所以考虑枚举#点.发现以\(i\)为中心的双倍回文的左半部分是个回文串,其中心一定位于\(i-\frac{pal[i]-1}2\)到\(i-1\)之间 ...

  6. 如何将 不确定的有穷自动机(NFA) 转化为 确定的有穷自动机(DFA) 并将DFA最简化

    一.从NFA到DFA的转换 例如下图: DFA的每个状态都是一个由NFA中的状态构成的集合,即NFA状态集合的一个子集 r =aa*bb*cc* 二.从带有ε-边的NFA到DFA的转换 r=0*1*2 ...

  7. thread 类详解

    java.lang.Thread类详解 一.前言 位于java.lang包下的Thread类是非常重要的线程类,它实现了Runnable接口,今天我们来学习一下Thread类,在学习Thread类之前 ...

  8. Python实现手机号自动判断性别

    本文性别判断主要依靠airtest中的自动化测试实现 通过自动对比支付宝页面男女图像,从而实现男女判断 代码如下: 男女判断函数: // An highlighted block def numbe( ...

  9. Java调用明华RF读写器DLL文件的方法

    首先jdk必须得是32位的,IDE也必须是32位的(我用的idea,所以为了使用32位的,下载了2018年1月版本的). 明华RF读写器演示文件提供了一份名为mwrf32.dll的动态链接库文件 ja ...

  10. 多线程模拟生产者消费者示例之BlockQueue

    public class Test { public static void main(String[] args){ //创建一个阻塞队列,边界为1 BlockingQueue<String& ...