目录

题目链接

bzoj3693: 圆桌会议

题解

对与每个人构建二分,问题化为时候有一个匹配取了所有的人

Hall定理——对于任意的二分图G,G的两个部分为X={x1,x2,…,xn}和Y={y1,y2,…,ym},

存在一个匹配M使得|M|=|X|的充要条件为对于X的任意一个子集A,与A相邻的点集记为T(A),一定有|T(A)|≥|A|

拆环为链

对于任意的区间[L,R],长度R-L+1,将所有区间[L,R]内的组插入操作求和为sum,如果sum > R - L + 1,显然不存在满足条件的匹配,否则一定存在解

对于有意义的区间[L,R]一定在给出的操作区间上

sum > R - L + 1 也就是 sum + P - 1 > Q

前面那部分线段树维护

对于每个右端点询问区间,每次把ai的值加到左端点上

对于右端点扫过去就行了

代码

/*
对与每个人构建二分,问题化为时候有一个匹配取了所有的人
> Hall定理——对于任意的二分图G,G的两个部分为X={x1,x2,…,xn}和Y={y1,y2,…,ym},
存在一个匹配M使得|M|=|X|的充要条件为对于X的任意一个子集A,与A相邻的点集记为T(A),一定有|T(A)|≥|A|
拆环为链
对于任意的区间[L,R],长度R-L+1,将所有区间[L,R]内的组插入操作求和为sum,如果sum > R - L + 1,显然不存在满足条件的匹配,否则一定存在解
对于有意义的区间[L,R]一定在给出的操作区间上
sum > R - L + 1 也就是 sum + P - 1 > Q
前面那部分线段树维护
对于每个右端点询问区间,每次把ai的值加到左端点上
对于右端点扫过去就行了
*/ #include<map>
#include<vector>
#include<cstdio>
#include<algorithm>
#define gc getchar()
#define pc putchar
#define LL long long
inline int read() {
int x = 0,f = 1;
char c = gc;
while(c < '0' || c > '9')c = gc;
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = gc;
return x * f;
}
void print(int x) {
if(x < 0) {
pc('-');
x = -x;
}
if(x >= 10) print(x / 10);
pc(x % 10 + '0');
}
const int maxn = 1000007;
struct Q {
int l,r,v;
bool operator < (const Q & k)const {
return r < k.r;
}
} q[maxn];
int d[maxn],cnt ,num;
int mx[maxn << 1],tag[maxn << 1];
int n,m;
#define ls x << 1,l,mid
#define rs x << 1 | 1,mid + 1,r
void update(int x) {
mx[x] = std::max(mx[x << 1],mx[x << 1 | 1]);
}
void build(int x,int l,int r) {
mx[x] = tag[x] = 0;
if(l == r) {
mx[x] = d[l] - 1; return;
}
int mid = l + r >> 1;
build(ls);
build(rs);
update(x);
}
inline void pushdown(int x) {
if(!tag[x]) return;
tag[x << 1] += tag[x]; tag[x << 1 | 1] += tag[x];
mx[x << 1] += tag[x]; mx[x << 1 | 1] += tag[x];
tag[x] = 0;
} void modify(int x,int l,int r,int L,int R,int val) {
if(L <= l && R >= r) {
tag[x] += val,mx[x] += val;
return;
}
pushdown(x);
int mid = l + r >> 1;
if(L <= mid) modify(ls,L,R,val);
if(R > mid) modify(rs,L,R,val);
update(x);
}
int query(int x,int l,int r,int L,int R) {
if(l >= L && R >= r) return mx[x];
pushdown (x);
int mid = l + r >> 1,ans = 0;
if(L <= mid) ans = std::max(query(ls,L,R),ans);
if(R > mid) ans = std::max(query(rs,L,R),ans);
return ans;
}
int main() {
int T = read();
for(int t = 1;t <= T;t += 1) {
cnt = num = 0;
n = read(),m = read();
bool flag = false;
LL sum = 0;
for(int i = 1;i <= n;++ i) {
q[i].l = read(),q[i].r = read(),q[i].v = read();
q[i].l ++;q[i].r ++;sum += q[i].v;
}
if(sum > m) {
puts("No"); continue;
}
cnt = n;
for(int i = 1;i <= n;++ i)
if(q[i].r < q[i].l) q[i].r += m;
else {
q[++cnt] = q[i];
q[cnt].l += m;q[cnt].r += m;
}
n = cnt;
for(int i = 1;i <= n;++ i) d[++ num] = q[i].l,d[++ num] = q[i].r;
std::sort(d + 1,d + num + 1);
std::sort(q + 1,q + n + 1);
build(1,1,n << 1);
for(int i = 1;i <= n;++ i)
q[i].l = std::lower_bound(d + 1,d + num + 1,q[i].l) - d,
q[i].r = std::lower_bound(d + 1,d + num + 1,q[i].r) - d;
for(int i = 1;i <= n;++ i) {
modify(1,1,n << 1,1,q[i].l,q[i].v);
//int k = query(1,1,n << 1,std::max(q[i].r - m + 1,1),q[i].r);
//print(k); pc('\n');
if(query(1,1,n << 1,std::max(q[i].r - m + 1,1),q[i].r) > d[q[i].r]) {
flag = true;
break;
}
}
puts(flag ? "No" : "Yes");
}
return 0;
}

bzoj3693: 圆桌会议 二分图 hall定理的更多相关文章

  1. 二分图hall定理应用+二分+双指针——cf981F(好题)

    /* 二分答案,判mid是否合法 如何判断:如果是在直线上,那么遍历匹配即可 现在在环上,即既可以向前匹配也可以向后匹配,那么将环拆开,扩展成三倍 显然a和b的匹配边是不可能交叉的,因为交叉必定没有不 ...

  2. BZOJ3693: 圆桌会议(Hall定理 线段树)

    题意 题目链接 Sol 好的又是神仙题... 我的思路:对于区间分两种情况讨论,一种是完全包含,另一种是部分包含.第一种情况非常好判断,至于计算对于一个区间[l, r]的$\sum a[i]$就可以了 ...

  3. Hall定理 二分图完美匹配

    充分性证明就先咕了,因为楼主太弱了,有一部分没看懂 霍尔定理内容 二分图G中的两部分顶点组成的集合分别为X, Y(假设有\(\lvert X \rvert \leq \lvert Y \rvert\) ...

  4. 【CF981F】Round Marriage(二分答案,二分图匹配,Hall定理)

    [CF981F]Round Marriage(二分答案,二分图匹配,Hall定理) 题面 CF 洛谷 题解 很明显需要二分. 二分之后考虑如果判定是否存在完备匹配,考虑\(Hall\)定理. 那么如果 ...

  5. Card Collector AtCoder - 5168(二分图匹配的HALL定理)

    题意: 给定一个H行W列的矩阵,在矩阵的格点上放带权值的卡片(一个点上能放多张). 现在从每行每列各拿走一张卡片(没有可以不拿),求可以拿到的最大权值. 卡片数N<=1e5,H,W<=1e ...

  6. BZOJ.3693.圆桌会议(Hall定理 线段树)

    题目链接 先考虑链.题目相当于求是否存在完备匹配.那么由Hall定理,对于任意一个区间[L,R],都要满足[li,ri]完全在[L,R]中的ai之和sum小于等于总位置数,即R-L+1.(其实用不到H ...

  7. TCO 2015 1A Hard.Revmatching(Hall定理)

    \(Description\) 给定一个\(n\)个点的二分图,每条边有边权.求一个边权最小的边集,使得删除该边集后不存在完备匹配. \(n\leq20\). \(Solution\) 设点集为\(S ...

  8. BZOJ.5404.party(树链剖分 bitset Hall定理)

    题目链接 只有指向父节点的单向道路,所以c个人肯定在LCA处汇合.那么就成了有c条到LCA的路径,求最大的x,满足能从c条路径中各选出x个数,且它们不同. 先要维护一条路径的数的种类数,可以树剖+每条 ...

  9. 【BZOJ2138】stone Hall定理+线段树

    [BZOJ2138]stone Description 话说Nan在海边等人,预计还要等上M分钟.为了打发时间,他玩起了石子.Nan搬来了N堆石子,编号为1到N,每堆包含Ai颗石子.每1分钟,Nan会 ...

随机推荐

  1. LOJ 3093: 洛谷 P5323: 「BJOI2019」光线

    题目传送门:LOJ #3093. 题意简述: 有 \(n\) 面玻璃,第 \(i\) 面的透光率为 \(a\),反射率为 \(b\). 问把这 \(n\) 面玻璃按顺序叠在一起后,\(n\) 层玻璃的 ...

  2. Linux Samba服务主配文件smb.conf中文详解【转】

    转自:https://blog.csdn.net/maotianwang/article/details/52524732 从网上找到描述比较详细的smb.conf中文解释: 服务名:smb 配置目录 ...

  3. phantomjs 中如何使用xpath

    function getNodeInfo(inputcsvPath) { var htmlnodeInfo = page.evaluate(function () { //_Ltg var XPATH ...

  4. Python poll IO多路复用

    一.poll介绍 poll本质上和select没有区别,只是没有了最大连接数(linux上默认1024个)的限制,原因是它基于链表存储的. 本人的另一篇博客讲了 python  select : ht ...

  5. openvpn用户管理、linux客户端配置及企业常用真实案例解析

    1.给企业用户分配VPN账户的流程: 添加拨号需要密码的用户 # source vars NOTE: If you run ./clean-all, I will be doing a rm -rf ...

  6. Java通过BCrypt加密

    一.概述 在用户模块,对于用户密码的保护,通常都会进行加密.我们通常对密码进行加密,然后存放在数据库中,在用户进行登录的时候,将其输入的密码进行加密然后与数据库中存放的密文进行比较,以验证用户密码是否 ...

  7. 输入一个数,求1到他 的和(for循环)

  8. java中文GBK和UTF-8编码转换乱码的分析

    原文:http://blog.csdn.net/54powerman/article/details/77575656 作者:54powerman 一直以为,java中任意unicode字符串,可以使 ...

  9. 洛谷 P4427 求和

    传送门啦 思路: 开始不肿么容易想到用倍增,但是想到需要求 $ Lca $ ,倍增这种常数小而且快的方法就很方便了.求 $ Lca $ 就是一个最普通的板子.那现在考虑怎么求题目中的结果. 树上差分可 ...

  10. HTTP协议 (1)

    HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议. HTT ...