题面

题目大意:

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

Solution:

  • 为什么加椅子?我们可以在最左边或最右边一直加直到人人都有座位。
  • 首先这道题目抽象成二分图很简单,然后我们可以只要求解出人与座位的最大匹配是多少,总人数减去即可,但跑二分图最大匹配显然会超时,我们就可以往霍尔定理方面想。
  • 然后你还需要知道一个霍尔定理推论:假设某个人的集合为\(X\),这个集合所对应的椅子的集合为\(Y\),如果\(|X|\leq|Y|\),则具有完美匹配,如果\(|X|\geq|Y|\),则\(X\)至少要删去\(|X|-|Y|\)个元素,才能有完备匹配,我们定义\(\Gamma(X)=|X|-|Y|\)。

在这题里,这个就是至少需要添加的椅子数目,所以我们要找出最大的\(\Gamma(X)\)

  • 接下来我们就来分析怎么找出最大的\(\Gamma(X)\),因为\(X\)不具有任何性质,不好下手,我们考虑\(Y\)有啥特点,他一定是\([1,l]\bigcup[r,m]\),然后我们可以通过这个\(Y\)确定\(|X|\),所以会有一下做法

法一:暴力枚举

  • 暴力枚举\(l,r\),椅子的个数为\(l+m-r+1\),通过上面的定理处理出答案,找出\(\Gamma\)最大值。时间复杂度:\(O(n^2)\)貌似会更高到三方

法二:与其说是法二不如说是法一优化

  • 我们考虑上面的算法哪一些地方是冗余的。假设我们枚举出\(l\),根据法一,我们会枚举出所有的\(r\),显然不用枚举所有的,实际上只有找出这个\(l\)对应后面的\(r\)算出来的最大值,如何快速查询出最大值,我们考虑使用线段树。
  • 具体如何优化这个问题:计算式子是人数\(-(l+m-r+1)\)。
  • 因为固定了\(l\),我们可以确定现在最多有多少人,总人数与\(l'\)有关(\(l'<l\))所以我们把\(l\)从小到大排序,把人数不断往线段树里面丢。
  • 具体多少人根据\(r\)决定,某一个人要加入计算的人数内,必须是他所允许的所有椅子范围都在讨论范围内,比如这个\(l=l_i\),那么\(0\leq r\leq r_i\)的人数都可以加一(因为我们此时\(l\)是固定的,保证了这个人\(l\)在范围内,如果枚举的\(r_j \leq r_i\),那么这个人数是要在算\(l \rightarrow r_j\)时算进去的)。
  • 如果上面你看懂了,那就很好办了,我们会发现对于枚举的\(r\),式子中的人数\(-m-1+r\)是一样的,人数我们是在推进\(l\)同时加入线段树,\(-m-1+r\)我们就可以提前加入线段树(建树)
  • 对于一种特殊的情况,比如说:\(l_i=1,r_i=1\),那么他能放的范围为所有,所以我们要判断\(m-n\)为答案的情况
  • 对于普通枚举\(l\),我们没必要考虑全部集合情况,所以我们就只用在线段树\(l+2\rightarrow m+1\)找出最大值减去\(l\),得到的答案与\(ans\)取\(max\)就\(ok\)啦

  • 下面我们来将乱搞做法,我们把人按\(l\)排序,枚举到人后把他可以座椅子的范围用线段树标记,然后算出总可以坐的椅子数与人数相比较,求出每次\(ans\)的\(max\),一开始错两个点,然后排了两个序,算两次就只错一个点了。这个方法显然是不对哒!!因为显然有一些人的子集没有枚举到。

这道题好理解吧(毛线,我起码看了一个下午才看懂,去吃饭的路上突然懂了23333)

对了贪心也可以过这道题,只不过做法没这么优美罢了

Attention:

  1. 线段树是从\(0\rightarrow m+1\),因为人的\(l,r\)包含\(0,m+1\)
  2. 特殊情况,\(|X|=n\)
  3. 枚举出\(l\)后,找最大值一定是从\([l+1,m+1]\)中找

First, 你枚举的\(r\)要\(>l\)。

Second,\(|X|=n\)已经被考虑(没那个必要了,其实你从\(l+1\)开始也不影响)

Code:

  1. //It is coded by ning_mew on 7.16
  2. #include<bits/stdc++.h>
  3. #define ls(x) (x*2)
  4. #define rs(x) (x*2+1)
  5. using namespace std;
  6. const int maxn=2e5+7,inf=1e9+7;
  7. int n,m,ans=0;
  8. struct Opt{int l,r;}p[maxn];
  9. struct Node{int lazy,maxx;}node[maxn*4];
  10. bool cmp(const Opt &A,const Opt &B){return A.l<B.l;}
  11. void pushdown(int num,int nl,int nr){
  12. if(!node[num].lazy)return;
  13. int lz=node[num].lazy; node[num].lazy=0;
  14. node[ls(num)].maxx+=lz;node[ls(num)].lazy+=lz;
  15. node[rs(num)].maxx+=lz;node[rs(num)].lazy+=lz;
  16. }
  17. void update(int num){node[num].maxx=max(node[ls(num)].maxx,node[rs(num)].maxx);}
  18. void build(int num,int nl,int nr){
  19. node[num].lazy=0; if(nl==nr){node[num].maxx=nr-m-1;return;}
  20. int mid=(nl+nr)/2;
  21. build(ls(num),nl,mid);build(rs(num),mid+1,nr);
  22. update(num);
  23. }
  24. void add(int num,int nl,int nr,int ql,int qr,int ad){
  25. if(ql<=nl&&nr<=qr){node[num].maxx+=ad;node[num].lazy+=ad;return;}
  26. if(nr<ql||qr<nl)return;
  27. int mid=(nl+nr)/2;pushdown(num,nl,nr);
  28. add(ls(num),nl,mid,ql,qr,ad);add(rs(num),mid+1,nr,ql,qr,ad);
  29. update(num);return;
  30. }
  31. int quary(int num,int nl,int nr,int ql,int qr){
  32. if(ql<=nl&&nr<=qr)return node[num].maxx;
  33. if(nr<ql||qr<nl)return -inf;
  34. int mid=(nl+nr)/2;pushdown(num,nl,nr);
  35. return max(quary(ls(num),nl,mid,ql,qr),quary(rs(num),mid+1,nr,ql,qr));
  36. }
  37. int main(){
  38. scanf("%d%d",&n,&m);
  39. for(int i=1;i<=n;i++)scanf("%d%d",&p[i].l,&p[i].r);
  40. sort(p+1,p+n+1,cmp);p[n+1].l=inf;
  41. build(1,0,m+1);
  42. for(int i=1;i<=n;i++){
  43. add(1,0,m+1,0,p[i].r,1);
  44. if(p[i].l!=p[i+1].l&&p[i].l<=m-1)ans=max(ans,quary(1,0,m+1,p[i].l+2,m+1)-p[i].l);
  45. }ans=max(ans,n-m);printf("%d\n",ans);
  46. return 0;
  47. }

博主蒟蒻,随意转载。但必须附上原文链接:http://www.cnblogs.com/Ning-Mew/,否则你会场场比赛暴0!!!

【题解】 AtCoder ARC 076 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. [arc076F]Exhausted?[霍尔定理+线段树]

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

  4. arc076 F - Exhausted? (霍尔定理学习)

    题目链接 Problem Statement There are M chairs arranged in a line. The coordinate of the i-th chair ($$$1 ...

  5. [BZOJ3693]圆桌会议[霍尔定理+线段树]

    题意 题目链接 分析 又是一个二分图匹配的问题,考虑霍尔定理. 根据套路我们知道只需要检查 "区间的并是一段连续的区间" 这些子集. 首先将环倍长.考虑枚举答案的区间并的右端点 \ ...

  6. [BZOJ2138]stone[霍尔定理+线段树]

    题意 一共有 \(n\) 堆石子,每堆石子有一个数量 \(a\) ,你要进行 \(m\) 次操作,每次操作你可以在满足前 \(i-1\) 次操作的回答的基础上选择在 \([L_i,R_i]\) 区间中 ...

  7. [BZOJ1135][POI2009]Lyz[霍尔定理+线段树]

    题意 题目链接 分析 这个二分图匹配模型直接建图的复杂度太高,考虑霍尔定理. 对于某些人组成的区间,我们只需要考虑他们的并是一段连续的区间的集合.更进一步地,我们考虑的人一定是连续的. 假设我们考虑的 ...

  8. AtCoder Regular Contest 076 F - Exhausted?

    题意: n个人抢m个凳子,第i个人做的位置必须小于li或大于ri,问最少几个人坐不上. 这是一个二分图最大匹配的问题,hall定理可以用来求二分图最大匹配. 关于hall定理及证明,栋爷博客里有:ht ...

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

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

随机推荐

  1. 06_Hadoop分布式文件系统HDFS架构讲解

    mr  计算框架 假如有三台机器 统领者master 01  02  03  每台机器都有过滤的应用程序 移动数据 01机== 300M  >mr 移动计算  java程序传递给各个机器(mr) ...

  2. Java 验证码详解

    1 使用Servlet实现验证码,涉及的知识点主要为java 绘图技术与session保存数据. HTML页面 <html> <image src='images/logo1.jpg ...

  3. Azure系列2.1.10 —— CloudBlobClient

    (小弟自学Azure,文中有不正确之处,请路过各位大神指正.) 网上azure的资料较少,尤其是API,全是英文的,中文资料更是少之又少.这次由于公司项目需要使用Azure,所以对Azure的一些学习 ...

  4. CentOS7 下面安装jdk1.8

    1. 卸载已有的jdk rpm -qa |grep jdk |xargs rpm -e --nodeps 2. 使用xftp上传 jdk 的文件我这里上传的是 jdk-8u121-linux-x64. ...

  5. cookie,localStorage和sessionStorage区别

    三者的异同 特性 Cookie localStorage sessionStorage 数据的生命期 一般由服务器生成,可设置失效时间.如果在浏览器端生成Cookie,默认是关闭浏览器后失效 除非被清 ...

  6. hive字符函数

  7. 老男孩python学习自修第五天【集合】

    特点: (1)无序 (2)不重复 使用场景: (1)关系测试 (2)去重 x & y 求交集 x | y 求并集 x - y 求差集 x ^ y 求对称差集 x.intersection(y) ...

  8. vscode git设置

    vscode只能打开一下界面: 在setting.path增加git.path选项,再使用linux的方法配置路径,就是使用D:/../bin/git.exe而不是\\ 重启vscode,git设置即 ...

  9. 转载 -- jquery easyui datagrid 动态表头 + 嵌套对象属性展示

    代码功能: 1.datagrid 的表头由后台生成,可以配置在数据库 2.datagrid 的列绑定数据 支撑嵌套对象 $(function() { var columns = new Array() ...

  10. onkeyup+onafterpaste 只能输入数字和小数点--转载

    JS判断只能是数字和小数点 1.文本框只能输入数字代码(小数点也不能输入)<input onkeyup="this.value=this.value.replace(/\D/g,'') ...