题目链接

Problem Statement
There are M chairs arranged in a line. The coordinate of the i-th chair ($$$1≤i≤M$$$) is $$$i$$$.
N people of the Takahashi clan played too much games, and they are all suffering from backaches. They need to sit in chairs and rest, but they are particular about which chairs they sit in. Specifically, the i-th person wishes to sit in a chair whose coordinate is not greater than Li, or not less than $$$R_i$$$. Naturally, only one person can sit in the same chair.
It may not be possible for all of them to sit in their favorite chairs, if nothing is done. Aoki, who cares for the health of the people of the Takahashi clan, decides to provide additional chairs so that all of them can sit in chairs at their favorite positions.
Additional chairs can be placed at arbitrary real coordinates. Find the minimum required number of additional chairs. Constraints

Input
Input is given from Standard Input in the following fomat:
$$$N$$$ $$$M$$$
$$$L_1$$$ $$$R_1$$$
:
$$$L_N$$$ $$$R_M$$$
Output

Print the minimum required number of additional chairs.


Input
4 4
0 3
2 3
1 3
3 4
Output
0
Input
7 6
0 7
1 5
3 6
2 7
1 6
2 6
3 7
Output
2
Input
3 1
1 2
1 2
1 2
Output
2
Input
6 6
1 6
1 6
1 5
1 5
2 6
2 6
Output
2

参考了这篇大佬的博客

【题意】

有$$$m$$$个座位,分别位于坐标为$$$1, 2, 3, ..., m$$$的地方;$$$n$$$个客人,第$$$i$$$位客人只坐位于$$$[0, l_i]\cup[r_i, \infty]$$$的座位。每个座位只能坐一个人,问最少需要添加几个座位才能使所有人坐下?

【分析】

首先说明一下霍尔定理的前提,已知点集X=$$$\{x_1, x_2, ..., x_n\}$$$, Y=$$$\{y_1, y_2, ..., y_m\}$$$,和边集E,E中每条边只能连接 X 与 Y 中的一对点;如果X中的k个点各自经过E与Y中k个不同的点相连,则称形成了一个大小为k的配对。

霍尔定理给出了在X中存在n个点的配对的充分必要条件——对任何一个大小为k的X(k≤n)的子集,Y至少有k个点经过E与它们相连。用公式来表达就是,定义$$$\omega$$$(X)表示Y中一共有几个点经过E与集合X相连,那么霍尔定理就是 $$$\forall$$$ X$$$_1$$$ $$$\subset$$$ X, |X$$$_1$$$| ≤ |$$$\omega$$$(X$$$_1$$$)|

在这道题中,可以这样使用霍尔定理:假设添加t个座位后,所有人都能坐下,也就是存在n个人的配对,那么一定满足对任意一个客人的集合X,有

|X| ≤ |$$$\omega$$$(X)+t|

$$$\Leftrightarrow$$$ |X| ≤ |$$$\omega$$$(X)| +t

$$$\Leftrightarrow$$$ |X| - |$$$\omega$$$(X)| ≤ t

那么t的最小值就是 max{ |X| - |$$$\omega$$$(X)| },因为$$$\omega$$$(X)一定是[1, L]$$$\cup$$$[R,m]的形式,可以改写为L + m - R +1

答案整理为max{ |X| + R - L - m -1 },在霍尔定理的帮助下,解题思路转化为,只需要遍历所有的客人的子集,就能算出来最大值了,不过遍历子集的代价太大,可以转而遍历(L, R)的区间。若固定L,只需要求max{ |X| + R },这个操作可以用线段树来完成,对每个L,处理每个R$$$_i$$$都让[L, R$$$_i$$$]内的数全部+1,为了选择最大的|X| + R,可以把所有结点初始化为R。

由于只关心固定L,[X]+R最大值,为了降低复杂度,可以直接在L$$$_1$$$处理完的基础上继续处理L$$$_2$$$的每个R$$$_i$$$,也就是说L$$$_2$$$不再单独考虑,直接和小的L结合到一起。

【代码】

因为使用了线段树,所以代码量略大,如果不看线段树的代码,其实核心部分很简洁。

#include <stdio.h>
#include <vector>
using std::vector; #define N_max 200005 #define left(x) ((x)<<1)
#define right(x) (((x)<<1)|1)
#define mid(l,r) (l+((r-l)>>1))
#define max(a,b) ((a)>(b)?(a):(b))
int lch[N_max << ], rch[N_max << ], lzy[N_max << ], val[N_max << ]; inline void lzydown(int cur)
{
if(lzy[cur])
{
int l = left(cur), r = right(cur);
lzy[l] += lzy[cur];
lzy[r] += lzy[cur];
val[l] += lzy[cur];
val[r] += lzy[cur];
lzy[cur] = ;
}
} inline void updup(int cur)
{
val[cur] = max(val[left(cur)], val[right(cur)]);
} void build(int cur, int cl, int cr)
{
lch[cur] = cl; rch[cur] = cr;
if (cl == cr) {
val[cur] = cr;
return;
}
int m = mid(cl, cr);
build(left(cur), cl, m);
build(right(cur), m + , cr);
updup(cur);
} void add(int cur,int cl,int cr)
{
if(lch[cur]==cl&&rch[cur]==cr)
{
lzy[cur]++;
val[cur]++;
return;
}
lzydown(cur);
int m = mid(lch[cur],rch[cur]);
if (cr <= m)
{
add(left(cur), cl, cr);
}
else if(cl>m)
{
add(right(cur), cl, cr);
}
else
{
add(left(cur), cl, m);
add(right(cur), m + , cr);
}
updup(cur);
} int query(int cur,int cl,int cr)
{
if (lch[cur] == cl&&rch[cur] == cr)
{
return val[cur];
}
int m = mid(lch[cur], rch[cur]);
lzydown(cur);
if (cr <= m)
{
return query(left(cur), cl, cr);
}
else if (cl>m)
{
return query(right(cur), cl, cr);
}
else
{
int ql= query(left(cur), cl, m);
int qr= query(right(cur), m + , cr);
return max(ql, qr);
}
return -;
} vector<int> ipt[N_max];
int ans = ;
int main()
{
int n, m;
scanf("%d %d", &n, &m);
ans = max(,n - m);
int a[];
for(int i=;i<n;++i)
{
scanf("%d %d", a, a + );
ipt[a[]].push_back(a[]);
}
build(, , m + );
for(int l=;l<=m;++l)
{
int sz = ipt[l].size();
for(int t=;t<sz;++t)
{
int r = ipt[l][t];
add(, , r);
}
int temp = query(, l + , m + ) - m - l - ;
ans = max(ans, temp);
}
printf("%d", ans);
return ;
}

arc076 F - Exhausted? (霍尔定理学习)的更多相关文章

  1. 【AtCoder ARC076】F Exhausted? 霍尔定理+线段树

    题意 N个人抢M个椅子,M个椅子排成一排 ,第i个人只能坐[1,Li]∪[Ri,M],问最多能坐多少人 $i$人连边向可以坐的椅子构成二分图,题意即是求二分图最大完美匹配,由霍尔定理,答案为$max( ...

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

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

  3. [AtCoder ARC076] F Exhausted?

    霍尔定理 + 线段树? 咱学学霍尔定理... 霍尔定理和二分图完美匹配有关,具体而言,就是定义了二分图存在完美匹配的充要条件: 不妨设当前二分图左端集合为 X ,右端集合为 Y ,X 与 Y 之间的边 ...

  4. [arc076F]Exhausted?[霍尔定理+线段树]

    题意 地上 \(1\) 到 \(m\) 个位置摆上椅子,有 \(n\) 个人要就座,每个人都有座位癖好:选择 \(\le L\) 或者 \(\ge R\) 的位置.问至少需要在两边添加多少个椅子能让所 ...

  5. 【题解】 AtCoder ARC 076 F - Exhausted? (霍尔定理+线段树)

    题面 题目大意: 给你\(m\)张椅子,排成一行,告诉你\(n\)个人,每个人可以坐的座位为\([1,l]\bigcup[r,m]\),为了让所有人坐下,问至少还要加多少张椅子. Solution: ...

  6. Codeforces 1009G Allowed Letters FMT,二分图,二分图匹配,霍尔定理

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF1009G.html 题目传送门 - CF1009G 题意 给定一个长度为 $n$ 的字符串 $s$ .并给定 ...

  7. [hdu5503]EarthCup[霍尔定理]

    题意 一共 \(n\) 只球队,两两之间会进行一场比赛,赢得一分输不得分,给出每只球队最后的得分,问能否构造每场比赛的输赢情况使得得分成立.多组数据 \(T\le 10,n\le 5\times 10 ...

  8. [CF981F]Round Marriage[二分+霍尔定理]

    题意 洛谷 分析 参考了Icefox 首先二分,然后考虑霍尔定理判断是否有完美匹配.如果是序列的话,因为这里不会出现 \(j<i,L(i)<L(j)\) 或者 \(j<i,R(i)& ...

  9. [CF1009G]Allowed Letters[贪心+霍尔定理]

    题意 给你一个长为 \(n\) 的串,字符集为 \(a,b,c,d,e,f\) .你可以将整个串打乱之后重新放置,但是某些位置上有一些限制:必须放某个字符集的字符.问字典序最小的串,如果无解输出 &q ...

随机推荐

  1. Codeforces Round #460 (Div. 2) 前三题

    Problem A:题目传送门 题目大意:给你N家店,每家店有不同的价格卖苹果,ai元bi斤,那么这家的苹果就是ai/bi元一斤,你要买M斤,问最少花多少元. 题解:贪心,找最小的ai/bi. #in ...

  2. Ajax跨域请求怎么解决?

    前言 项目中需要将第三方系统中,对应用户的代办消息集成到系统中.对方提供了获取对应用户的接口url,但是由于两边的系统是部署到客户现场不同IP的虚机上的,所以进行ajax请求的时候是属于跨域请求的.之 ...

  3. R语言使用过程中出现的问题--attach()函数的使用

    使用attach(file)时,一定要配合使用detach(file),否则再此运行程序时极易出现问题,The following objects are masked ... 此外工作空间中不能有与 ...

  4. javaweb(五)——Servlet开发(一)

    一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...

  5. Selenium(Python)页面对象+数据驱动测试框架

    整个工程的目录结构: 常用方法类: class SeleniumMethod(object): # 封装Selenium常用方法 def __init__(self, driver): self.dr ...

  6. [JSON].valueOf( keyPath )

    语法:[JSON].valueOf( keyPath ) 返回:[任意类型 | null] 说明:获取键名路径原值,它保留原始值的类型 示例: b = sysFile.binary("tes ...

  7. Vuejs 基础与语法

    Vue 实例 创建第一个实例 {{}} 被称之为插值表达式.可以用来进行文本插值. <!DOCTYPE html> <html lang="en"> < ...

  8. ubuntu networking 与 network-manager

    刚遇到的坑,因为操作不当导致网络中断,于是手动配置了/etc/network/interfaces , 修复了系统之后发现ubuntu-desktop中的有线链接不见了,百度了一下说是networki ...

  9. jstat命令

    jstat命令使用 jstat命令可以查看堆内存各部分的使用量,以及加载类的数量.命令的格式如下: jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数] 注意:使用的jdk版本是 ...

  10. [转载] RCNN/SPP/FAST RCNN/FASTER RCNN/YOLO/SSD算法简介

    RCNN: RCNN(Regions with CNN features)是将CNN方法应用到目标检测问题上的一个里程碑,由年轻有为的RBG大神提出,借助CNN良好的特征提取和分类性能,通过Regio ...