AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图

链接

AtCoder

大意

在数轴上放上n个点,点i可能的位置有\(x_i\)或者\(y_i\)

思路

首先最大值最小,考虑二分答案。

如何check呢。

只有两个坐标,考虑2-sat.

可是边有点多,存不下来,考虑线段树优化建图。

如何建图。

先按照做坐标排序,我们有两个点的范围

[id[x]-mid,id[x]+mid],[id[y]-mid,id[y]+mid]。

这个显然是z选了,区间内就不选,那就选另一个喽。

连区间的补集是不明智的,连点的补集。

细节

这里build直接交换了两个点的位置,%Refun

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+7;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int n,id[N],mmp,val[N],pos[N];
struct edge {
int id,val,type;
bool operator < (const edge &b) const {
return val<b.val;
}
}a[N];
struct node {int v,nxt;}e[N<<1];
int head[N],tot;
void add(int u,int v) {
e[++tot].v=v;
e[tot].nxt=head[u];
head[u]=tot;
}
int low[N],dfn[N],stak[N],top,cnt,vis[N],belong[N],scc;
void clear() {
cnt=scc=tot=0;
mmp=n+n;
memset(head,0,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(id,0,sizeof(id));
}
void tarjan(int u) {
low[u]=dfn[u]=++cnt;
vis[u]=1;
stak[++top]=u;
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(!dfn[v]) {
tarjan(v);
low[u]=min(low[u],low[v]);
} else if(vis[v]) {
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]) {
++scc;
while(stak[top]!=u) {
vis[stak[top]]=0;
belong[stak[top]]=scc;
top--;
}
vis[stak[top]]=0;
belong[stak[top]]=scc;
top--;
}
}
namespace seg {
#define ls rt<<1
#define rs rt<<1|1
void build(int l,int r,int rt) {
if(l==r) return id[rt]=pos[((a[l].id-1)^1)+1],void();
int mid=(l+r)>>1;
id[rt]=++mmp;
build(l,mid,ls);
build(mid+1,r,rs);
add(id[rt],id[ls]),add(id[rt],id[rs]);
}
void update(int u,int L,int R,int l,int r,int rt) {
if(L>R) return;
if(L<=l&&r<=R) return add(u,id[rt]);
int mid=(l+r)>>1;
if(L<=mid) update(u,L,R,l,mid,ls);
if(R>mid) update(u,L,R,mid+1,r,rs);
}
}
bool check(int mid) {
clear();
seg::build(1,n+n,1); for(int i=1;i<=n+n;++i) {
int l=upper_bound(val+1,val+n+n+1,val[i]-mid)-val;
int r=lower_bound(val+1,val+n+n+1,val[i]+mid)-val-1;
seg::update(i,max(l,1),i-1,1,n+n,1);
seg::update(i,i+1,min(r,2*n),1,n+n,1);
// printf("%d -> [%d,%d]\n",i,l,i-1);
// printf("%d -> [%d,%d]\n",i,i+1,r);
}
for(int i=1;i<=2*n;++i)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=2*n;i+=2)
if(belong[pos[i]]==belong[pos[i+1]]) return 0;
return 1;
}
int main() {
n=read();
for(int i=1;i<=n;++i) {
a[2*i-1].id=2*i-1,a[2*i-1].val=read();
a[2*i].id=2*i,a[2*i].val=read();
}
sort(a+1,a+1+n+n);
for(int i=1;i<=n+n;++i) pos[a[i].id]=i,val[i]=a[i].val;
int l=0,r=1e9,ans=0;
while(l<=r) {
int mid=(l+r)>>1;
if(check(mid)) l=mid+1,ans=mid;
else r=mid-1;
}
printf("%d\n",ans);
return 0;
}

AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图的更多相关文章

  1. AtCoder Regular Contest 069 F - Flags

    题意: 有n个点需要摆在一个数轴上,每个点需要摆在ai这个位置或者bi上,问怎么摆能使数轴上相邻两个点之间的距离的最小值最大. 二分答案后显然是个2-sat判定问题,因为边很多而连边的又是一个区间,所 ...

  2. AtCoder Regular Contest 063 F : Snuke’s Coloring 2 (线段树 + 单调栈)

    题意 小 \(\mathrm{C}\) 很喜欢二维染色问题,这天他拿来了一个 \(w × h\) 的二维平面 , 初始时均为白色 . 然后他在上面设置了 \(n\) 个关键点 \((X_i , Y_i ...

  3. AtCoder Regular Contest 069

    1. C - Scc Puzzle 计算scc的个数,先判断s个数需要多少个cc,多的cc,每四个可以组成一个scc.注意数据范围,使用long long. #include<bits/stdc ...

  4. AtCoder Regular Contest 076 F - Exhausted?

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

  5. AtCoder Regular Contest 082 F

    Problem Statement We have a sandglass consisting of two bulbs, bulb A and bulb B. These bulbs contai ...

  6. AtCoder Regular Contest 074 F - Lotus Leaves

    题目传送门:https://arc074.contest.atcoder.jp/tasks/arc074_d 题目大意: 给定一个\(H×W\)的网格图,o是可以踩踏的点,.是不可踩踏的点. 现有一人 ...

  7. AtCoder Regular Contest 081 F - Flip and Rectangles

    题目传送门:https://arc081.contest.atcoder.jp/tasks/arc081_d 题目大意: 给定一个\(n×m\)的棋盘,棋盘上有一些黑点和白点,每次你可以选择一行或一列 ...

  8. AtCoder Regular Contest 069 D

    D - Menagerie Time limit : 2sec / Memory limit : 256MB Score : 500 points Problem Statement Snuke, w ...

  9. AtCoder Regular Contest 069 D - Menagerie 枚举起点 模拟递推

    arc069.contest.atcoder.jp/tasks/arc069_b 题意:一堆不明身份的动物排成一圈,身份可能是羊或狼,羊一定说实话,狼一定说假话.大家各自报自己的两边是同类还是不同类, ...

随机推荐

  1. 开源规则引擎 Drools 学习笔记 之 -- 1 cannot be cast to org.drools.compiler.kie.builder.impl.InternalKieModule

    直接进入正题 我们在使用开源规则引擎 Drools 的时候, 启动的时候可能会抛出如下异常: Caused by: java.lang.ClassCastException: cn.com.cheng ...

  2. K8S学习笔记之K8S日志搜集实战

    详细参考这篇文章,几乎覆盖了了K8S的各种日志搜集方案 https://juejin.im/post/5b6eaef96fb9a04fa25a0d37#heading-8

  3. 【转载】socket通信-C#实现tcp收发字符串文本数据

    在日常碰到的项目中,有些场景需要发送文本数据,也就是字符串,比如简单的聊天文字,JSON字符串等场景.那么如何如何使用SharpSocket来收发此类数据呢?其中要掌握的关键点是什么呢? 点击查看原博 ...

  4. docker-compose进阶

    笔者在前文<Docker Compose 简介>和<Dcoker Compose 原理>两篇文章中分别介绍了 docker compose 的基本概念以及实现原理.本文我们将继 ...

  5. webpack 里的 import, exports 实现原理

    在使用 webpack 对脚本进行打包, 在开发中, 每个文件中都会使用 import 语句来导入一些功能,又会使用 export 语句导出一些功能,为了研究 import 和 export 原理,研 ...

  6. English--定语从句

    English|定语从句 从介绍从句开始,英语的句子已经开始逐渐复杂了!做好心理准备,三大从句介绍完毕,会介绍分词短语.废话不多说,直接开始干! 前言 目前所有的文章思想格式都是:知识+情感. 知识: ...

  7. 45、导航钩子函数中使用next()和next('\指定路径')的区别:

    当在router.beforeEach((to, from, next) 钩子函数中使用: 1.使用next()时,直接跳转到下一页,没有再执行导航钩子函数 2.使用next('指定路径')跳转到指定 ...

  8. odex vdex art区别

    一.vdexpackage 直接转化的 可执行二进制码 文件:1.第一次开机就会生成在/system/app/<packagename>/oat/下:2.在系统运行过程中,虚拟机将其 从 ...

  9. windows jupyter notebook 切换默认环境

    windows jupyter notebook 切换默认环境 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog ...

  10. Golang: 模拟搜索引擎爬虫

    最近网站需要针对百度做 SEO 优化,用 Go 语言写了个测试程序,模拟一下百度的爬虫,看看返回的内容是否正确. 代码很简单,就是发送一个请求,把百度相关的信息放入请求头中即可,代码如下: packa ...