目录

题目链接

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. vsftpd控制用户禁止访问上级目录 只能访问自己目录

    涉及文件: vsftpd.conf chroot_list_file=/etc/vsftpd.chroot_list 如果设置为 chroot_local_user=YES chroot_list_e ...

  2. v4l2文档之——color and format【转】

    转自:https://blog.csdn.net/zoe6553/article/details/17715407 v4l2文档第五A--颜色与格式    颜色与格式这是不定期发布的关于写视频驱动程序 ...

  3. vs2010补丁

    背景 我都不知道这是干啥的了.想起.net真是一把鼻涕一把泪.搞了这么久.net,也被它坑了好多.有这时间搞搞开源东西多好.看见下面还有tfs,想起当时有个java同事竟然用vss管理java代码,后 ...

  4. linux下ssh远程连接工具SecureCRT和xshell编码设置

    默认的编码有时候显示乱码,需要切换到utf-8 xshell的设置 多个会话窗口执行同样命令 中文界面:

  5. tomcat参数调优

    在做java开发时尤其是大型软件开发时经常会遇到内存溢出的问题,比如说OutOfMemoryError等.这是个让开发人员很痛苦.也很纠结的问题,因为我们有时不知道什么样的操作导致了这种问题的发生.所 ...

  6. TomCat安装配置教程

    一.JDK的安装与配置 1.从官网下载jdk,注意是jdk不是jre.最好从官网下载,也可以直接度娘. 2.下载完毕后,安装jdk,​直接按照安装向导的提示安装即可,安装时可以自己选择安装路径,我的安 ...

  7. 实现div里的内容垂直居中

    ---恢复内容开始--- 在项目中我们会遇到这种情况,一个div的宽固定,里面的内容长度不定,不管是一行还是多行,都要垂直居中,有俩个实现方法: 1.使用absolute,top:50%,transf ...

  8. Vue.js+Koa2移动电商实战 笔记

    地址:http://jspang.com/ https://github.com/shenghy/SmileVue 1.vant  https://www.youzanyun.com/zanui/va ...

  9. python 全栈开发,Day69(Django的视图层,Django的模板层)

    昨日内容回顾 相关命令: 1 创建项目 django-admin startproject 项目名称 2 创建应用 python manage.py startapp app名称 3 启动项目 pyt ...

  10. 去掉li列表前面的空格

    如果用li做列表的话,li前面的空格其实是li的默认样式.因为li位于ul里面,所以,有空格代表了ul肯定有padding值. ul { margin: 0px; padding: 0px; }