ARC076 F - Exhausted?

[题目大意]

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

[Solution]

本题考察对霍尔定理的理解, $对于二分图G=<V_1, V_2, E> , 设|V_1| < |V_2| , 则G中存在V_1 到V_2的完美匹配当且仅当对于任意S\subset V_1, 对于S的邻域N(S), 均有|S| \le |N(S)| $

而霍尔定理有一个推论, 就是若使G 中存在完美匹配, 则最少补充\(max\{0, |S| - |N(S)|\}\) 条边

回到本题, 对于一个人, 把他看做左部点, 把座位1到m看做右部, 将客人向所有\(i\in[1, l_i] \cup [r_i, m]\)连边

因为左部S所对应的右部节点的形式为\([1, l] \cup [r, m]\) 节点数为\(m - (r - l + 1)= m - r + l - 1\)

那么依据霍尔定理, 答案就是 \(|S| - m + r - l + 1\)

那么, 求出上述式子的最大值即可, 但是枚举S的复杂度太高, 于是考虑右部区间\([L, R]\) 找出对应的左部节点,所以可以将人\(l_i, r_i\) 按\(l_i\) 升序, 建一棵线段树存储\(r_i\) ,将右部节点映射上去, 并把初值设为i,。迭代\(l\) , 每次将左端点是\(l\)的\(r_i\), 更新入线段树, 即将\([l, r]\) 区间加一, 每次求出\([L, m]\)的最大值。

对于\(r_i = m + 1\)的点, 在额外建一个点m + 1,存储即可

#include <bits/stdc++.h>
#define for_(i,a,b) for (ll i = (a); i < (b); i++)
#define rep_(i,a,b) for (ll i = (a); i <= (b); i++)
#define ll long long
#define pii pair<int, int>
#define fi first
#define se second
#define sz(a) a.size()
#define all(v) v.begin(), v.end()
#define int long long
using namespace std;
const int maxn = 5e5 + 10, mod = 1e9 + 7;// mod = 1949777;
const double EPS = 1e-3;
int n, m;
vector<int> a[maxn];
struct segment_tree{
int N;
long long P;
vector<long long> ST, A, M, F; // A -> tag add / M -> tag mul /F -> tag max
segment_tree(int n) {
N = 1;
while(N < n) {
N *= 2;
}
ST = vector<long long>(4 * N - 1, 0);
A = ST;
M = vector<long long>(4 * N - 1, 1);
F = A;
P = 1e15;
}
void pushdown(int s, int t, int p) {
int l = 2 * p, r = 2 * p + 1, mid = s + ((t - s) >> 1);
if (M[p] != 1) {
M[l] *= M[p], M[l] %= P;
A[l] *= M[p], A[l] %= P;
ST[l] *= M[p], ST[l] %= P;
F[l] *= M[p], F[l] %= P;
M[r] *= M[p], M[r] %= P;
A[r] *= M[p], A[r] %= P;
ST[r] *= M[p], ST[r] %= P;
F[r] *= M[p], F[r] %= P;
M[p] = 1;
}
if (A[p] != 0) {
ST[l] += A[p] * (mid - s + 1), ST[l] %= P;
A[l] += A[p], A[l] %= P;
F[l] += A[p], F[l] %= P;
ST[r] += A[p] * (t - mid), ST[r] %= P;
A[r] += A[p], A[r] %= P;
F[r] += A[p], F[r] %= P;
A[p] = 0;
}
return;
}
void pushup(int p) {
int l = 2 * p, r = 2 * p + 1;
ST[p] = (ST[l] + ST[r]) % P;
F[p] = max(F[l], F[r]);
return;
}
void mul(int l, int r, int c, int s, int t, long long p) {
if (l <= s && t <= r) {
M[p] *= c, A[p] *= c, ST[p] *= c;
M[p] %= P, A[p] %= P, ST[p] %= P;
F[p] *= c, F[p] %= P;
return;
}
int mid = s + ((t - s) >> 1);
pushdown(s, t, p);
if (l <= mid) mul(l, r, c, s, mid, p * 2);
if (mid < r) mul(l, r, c, mid + 1, t, p * 2 + 1);
//(ST[p] = ST[p * 2] + ST[p * 2 + 1]) %= P;
pushup(p);
}
void add(int l, int r, int c, int s, int t, long long p) {
if (l <= s && t <= r) {
ST[p] += (t - s + 1) * c; ST[p] %= P;
A[p] += c; A[p] %= P;
F[p] += c, F[p] %= P;
return;
}
int mid = s + ((t - s) >> 1);
pushdown(s, t, p);
if (l <= mid) add(l, r, c, s, mid, 2 * p);
if (mid < r) add(l, r, c, mid + 1, t, 2 * p + 1);
//(ST[p] = ST[2 * p] + ST[2 * p + 1]) %= P;
pushup(p);
return;
}
long long getsum(int l, int r, int s, int t, int p) {
if (l <= s && t <= r) {
return ST[p];
}
int mid = s + ((t - s) >> 1);
pushdown(s, t, p);
long long res = 0;
if (l <= mid) res += getsum(l, r, s, mid, 2 * p), res %= P;
if (mid < r) res += getsum(l, r, mid + 1, t, 2 * p + 1), res %= P;
return res;
}
int getmax(int l, int r, int s, int t, int p) {
if (l <= s && t <= r) return F[p];
pushdown(s, t, p);
int mid = s + ((t - s) >> 1);
int res = -1e15;
if (l <= mid) res = max(res, getmax(l, r, s, mid, 2 * p));
if (mid < r) res = max(res, getmax(l, r, mid + 1, t, 2 * p + 1));
return res;
}
};
signed main() {
cin >> n >> m;
int ans = max(0LL, n - m);
m++; // 由于线段树板子是Indexed_1,所以坐标整体+1
segment_tree T(m + 2);
for (int i = 1; i <= m + 1; i++) T.add(i, i, i - 1, 1, m + 1, 1);
for (int i = 1; i <= n; i++) {
int u, v; cin >> u >> v;
u++, v++;
a[u].push_back(v);
}
for (int i = 1; i <= m; i++) {
for (int j = 0; j < (int)a[i].size(); j++) {
T.add(1, a[i][j], 1, 1, m + 1, 1);
}
ans = max(ans, -(i - 1) - (m - 1) - 1 + T.getmax(i + 1, m + 1, 1, m + 1, 1)); //即上文的式子
}
cout << ans << endl;
return 0;
}

arc076f F - Exhausted?的更多相关文章

  1. 2017国家集训队作业[arc076d/f][Exhausted?]

    2017国家集训队作业[arc076d/f][Exhausted?] 题意: ​ 有\(N\)个人,\(M\)把椅子,给出\(...L_i.R_i\)表示第\(i\)个人可以选择编号为\(1\sim ...

  2. AtCoder Regular Contest 076 F - Exhausted?

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

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

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

  4. [AtCoder ARC076] F Exhausted?

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

  5. AtCoder F - Exhausted?

    传送门 sxy题解: //Achen #include<algorithm> #include<iostream> #include<cstring> #inclu ...

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

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

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

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

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

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

  9. 【ARC076F】 Exhausted

    hall定理大概是匈牙利的理论基础吧 hall定理的内容:二分图\(G\)的的左部点点集为\(\rm X\),右部点点集为\(\rm Y\),设\(|\rm X|\leq |Y|\),则二分图\(G\ ...

  10. AtCoder Regular Contest 076

    在湖蓝跟衡水大佬们打的第二场atcoder,不知不觉一星期都过去了. 任意门 C - Reconciled? 题意:n只猫,m只狗排队,猫与猫之间,狗与狗之间是不同的,同种动物不能相邻排,问有多少种方 ...

随机推荐

  1. PTA1004 成绩排名 (20 分)

    PTA1004 成绩排名 读入 n(>0)名学生的姓名.学号.成绩,分别输出成绩最高和成绩最低学生的姓名和学号. 输入格式: 每个测试输入包含 1 个测试用例,格式为 第 1 行:正整数 n 第 ...

  2. 第9章 使用MVC为移动和客户端应用程序创建Web API(ASP.NET Core in Action, 2nd Edition)

    本章包括 创建Web API控制器以向客户端返回JSON 使用属性路由自定义URL 使用内容协商生成响应 使用[ApiController]属性应用通用约定 在前五章中,您已经完成了服务器端渲染ASP ...

  3. JS this指向相关

    function Foo() { getName = function() { console.log(1) } return this;}Foo.getName = function() { con ...

  4. Python数据可视化-条形图渐变颜色

    import pandas as pd from pyecharts.charts import Bar from pyecharts.commons.utils import JsCode data ...

  5. C语言和C++的区别与联系(详细)

    文章转自:https://blog.csdn.net/cherrydreamsover/article/details/81835976 在学习了C语言和C++之后,这两者之间的区别我们需要仔细的捋一 ...

  6. ZooKeeper启动报错,未成功开启服务

    1.问题示例 (1)启动ZooKeeper服务报错 [Hadoop@master ~]$ zkServer.sh statusZooKeeper JMX enabled by defaultUsing ...

  7. 我是如何被我的c++大作业榨干的

    手把手教你用git上传项目到GitHub(图文并茂,这一篇就够了),相信你一定能成功!! - 知乎 (zhihu.com) C++ 类对象数组_Slience_Perseverance的博客-CSDN ...

  8. 关与python面向对象的认识

    面向对象编程 类:从一堆对象中以抽象的方式把相同的特征归类得到. 抽象类 类 实列 子类抽象为父类,子类继承父类特征. 类实例化为实例,实例抽象为类. class Human(object): cen ...

  9. 定制centos发行版

    //轻量级Centos定制发行版==================================================================================== ...

  10. postman 8.7.0 下的cookie 禁用

    简介:以下过程描述在postman8.7.0中,如何禁用掉cookie,使每次请求都带空cookie去请求服务器. 有一个简单投票场景.投票连接是一个get请求, 类似如http://domain/t ...