ARC076 F Exhausted? Hall定理 + 线段树扫描线
题目大意:
有n个人,m个座位,每个人可以匹配的座位是[1, li] || [ri, m],可能有人不需要匹配座位(默认满足),问最少有多少人不能被满足。
题解:
首先可以看出这是一个二分图匹配,根据hall定理,我们只需要求出max(人的子集大小 - 被选出的人可以选的座位集合大小)。
但是枚举人的复杂度太高,所以考虑枚举座位集合,因为每个人的可选区间都是一段前缀or后缀,因此要表达一个合法的座位集合,我们只需要所有人中最右边的li和最左边的ri即可。
如图所示:

因此这个时候要使得尽可能接近max,就要把所有可选区间不超过我们当前枚举的区间的人都加进来。
可以使用扫描线,求出对于每个R,所有的L相对应的值。
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 400100
#define ac 1601000//error!!!数据范围是2 00000, 不是1开头!!! int n, m, ans = -INT_MAX, w;
int Head[AC], Next[ac], date[ac], tot;
int tree[ac], lazy[ac], l[ac], r[ac], l_[AC], r_[AC]; inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} inline void add(int f, int w)
{
date[++tot] = w, Next[tot] = Head[f], Head[f] = tot;
} inline void upmax(int &a, int b)
{
if(b > a) a = b;
} void pre()
{
n = read(), m = read();
for(R i = ; i <= n; i ++)
l_[i] = read(), r_[i] = read(), add(r_[i], i);
} inline void pushdown(int x)
{
if(lazy[x])
{
int ll = x * , rr = ll + ;
lazy[ll] += lazy[x], lazy[rr] += lazy[x];
tree[ll] += lazy[x], tree[rr] += lazy[x];//这里因为是+=,所以必须用lazy[x],不然会将lazy[ll]中的一些东西重复统计
lazy[x] = ;//最后才清空!!!!!!!!!!
}//error!!!是区间加,不是赋值,不能直接覆盖,要+=
} inline void update(int x)
{
tree[x] = max(tree[x * ], tree[x * + ]);
} void build(int x, int ll, int rr)
{
l[x] = ll, r[x] = rr;
if(ll == rr)
{
tree[x] = -ll + ;
return ;
}
int mid = (ll + rr) >> ;
build(x * , ll, mid);
build(x * + , mid + , rr);
update(x);
} void change(int x, int ll, int rr)
{
pushdown(x);
if(l[x] == ll && r[x] == rr)
{
lazy[x] += w, tree[x] += w;
return ;
}
int mid = (l[x] + r[x]) >> ;
if(rr <= mid) change(x * , ll, rr);
else if(ll > mid) change(x * + , ll, rr);
else
{
change(x * , ll, mid);
change(x * + , mid + , rr);
}
update(x);
} void find(int x, int ll, int rr)
{
pushdown(x);
if(l[x] == ll && r[x] == rr)
{
upmax(ans, tree[x]);
return ;
}
int mid = (l[x] + r[x]) >> ;
if(rr <= mid) find(x * , ll, rr);
else if(ll > mid) find(x * + , ll, rr);
else find(x * , ll, mid), find(x * + , mid + , rr);//这是取max啊,,,,
} void work()
{
int now;
ans = n - m;//r = 0的情况
for(R i = Head[m + ]; i; i = Next[i])
{
now = date[i], w = ;
change(, l_[now] + , m + );
//find(1, 4, 4);
}
//find(1, 4, 4);
upmax(ans, tree[]);
for(R i = m; i; -- i)
{
w = -;
change(, , i + );
for(R j = Head[i]; j; j = Next[j])
{
now = date[j], w = ;
change(, l_[now] + , i + );
}
find(, , i + );//左端点在后面就不合法了
}
printf("%d\n", ans);
} int main()
{
freopen("in.in", "r", stdin);
pre();
build(, , m + );//要多出一位来代表左端点取0的情况
work();//ri最大居然可以到m+1...
fclose(stdin);
return ;
}
ARC076 F Exhausted? Hall定理 + 线段树扫描线的更多相关文章
- 【AtCoder ARC076】F Exhausted? 霍尔定理+线段树
题意 N个人抢M个椅子,M个椅子排成一排 ,第i个人只能坐[1,Li]∪[Ri,M],问最多能坐多少人 $i$人连边向可以坐的椅子构成二分图,题意即是求二分图最大完美匹配,由霍尔定理,答案为$max( ...
- BZOJ.3693.圆桌会议(Hall定理 线段树)
题目链接 先考虑链.题目相当于求是否存在完备匹配.那么由Hall定理,对于任意一个区间[L,R],都要满足[li,ri]完全在[L,R]中的ai之和sum小于等于总位置数,即R-L+1.(其实用不到H ...
- BZOJ3693: 圆桌会议(Hall定理 线段树)
题意 题目链接 Sol 好的又是神仙题... 我的思路:对于区间分两种情况讨论,一种是完全包含,另一种是部分包含.第一种情况非常好判断,至于计算对于一个区间[l, r]的$\sum a[i]$就可以了 ...
- Codeforces 338E - Optimize!(Hall 定理+线段树)
题面传送门 首先 \(b_i\) 的顺序肯定不会影响匹配,故我们可以直接将 \(b\) 数组从小到大排个序. 我们考虑分析一下什么样的长度为 \(m\) 的数组 \(a_1,a_2,\dots,a_m ...
- LOJ.6062.[2017山东一轮集训]Pair(Hall定理 线段树)
题目链接 首先Bi之间的大小关系没用,先对它排序,假设从小到大排 那么每个Ai所能匹配的Bi就是一个B[]的后缀 把一个B[]后缀的匹配看做一条边的覆盖,设Xi为Bi被覆盖的次数 容易想到 对于每个i ...
- loj#6062. 「2017 山东一轮集训 Day2」Pair hall定理+线段树
题意:给出一个长度为 n的数列 a和一个长度为 m 的数列 b,求 a有多少个长度为 m的连续子数列能与 b匹配.两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当 ...
- 【BZOJ2138】stone Hall定理+线段树
[BZOJ2138]stone Description 话说Nan在海边等人,预计还要等上M分钟.为了打发时间,他玩起了石子.Nan搬来了N堆石子,编号为1到N,每堆包含Ai颗石子.每1分钟,Nan会 ...
- 模拟赛 怨灵退治 题解(Hall定理+线段树)
题意: 有 n 群怨灵排成一排,燐每秒钟会选择一段区间,消灭至多 k 只怨灵. 如果怨灵数量不足 k,则会消灭尽量多的怨灵. 燐作为一只有特点的猫,它选择的区间是不会相互包含的.它想要知道它每秒最多能 ...
- arc076 F - Exhausted? (霍尔定理学习)
题目链接 Problem Statement There are M chairs arranged in a line. The coordinate of the i-th chair ($$$1 ...
随机推荐
- zookeeper环境搭建(Linux)
安装zookeeper 安装jdk(此处省略) 解压tar包并配置变量环境 配置文件修改 将/usr/local/src/zookeeper-3.4.5/conf这个路径下的zoo_sample.cf ...
- admin添加用户时报错:(1452, 'Cannot add or update a child row: a foreign key constraint fails (`mxonline`.`django_admin_l
在stackoverflow找到答案: DATABASES = { 'default': { ... 'OPTIONS': { "init_command": "SET ...
- C语言学习记录_2019.01.29
C语言的灵魂:指针 #include <stdio.h> int main(int argc, char **argv) { printf("Hello, World!\n&q ...
- 糖果 南阳acm589
糖果 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 topcoder工作室的PIAOYIi超级爱吃糖果,现在他拥有一大堆不同种类的糖果,他准备一口气把它们吃完,可是 ...
- (数据科学学习手札06)Python在数据框操作上的总结(初级篇)
数据框(Dataframe)作为一种十分标准的数据结构,是数据分析中最常用的数据结构,在Python和R中各有对数据框的不同定义和操作. Python 本文涉及Python数据框,为了更好的视觉效果, ...
- HDU 1495 非常可乐 (只是转了个弯的广搜题)
N - 非常可乐 =========================================================================================== ...
- JSON初体验(一):JsonObject解析
在学校的呆了一段时间,马上又要回去工作了,不说了,我现在介绍一下json相关的内容 1.JSON数据格式(总的来说,json就是一个字符串) 1.整体结构 String json1 = "{ ...
- C#的特性Attribute
一.什么是特性 特性是用于在运行时传递程序中各种元素(比如类.方法.结构.枚举.组件等)的行为信息的声明性标签,这个标签可以有多个.您可以通过使用特性向程序添加声明性信息.一个声明性标签是通过放置在它 ...
- 【转】使用git提交项目到码云
一.git安装 1.首先在官方网站下载git工具,或者根据以下链接进行下载:http://download.csdn.net/detail/qq_27501889/9788879(此链接版本为git- ...
- P2966 [USACO09DEC]牛收费路径Cow Toll Paths
P2966 [USACO09DEC]牛收费路径Cow Toll Paths 题目描述 Like everyone else, FJ is always thinking up ways to incr ...