Description

​ 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离。

Input

​ 第一行一个整数 N。

​ 接下来 N 行每行两个整数 xi,yi

Output

​ 一个整数表示答案。

Sample Input

Sample #1
3
1 3
2 5
1 9 Sample #2
5
2 2
2 2
2 2
2 2
2 2 Sample #3
22
93 6440
78 6647
862 11
8306 9689
798 99
801 521
188 206
6079 971
4559 209
50 94
92 6270
5403 560
803 83
1855 99
42 504
75 484
629 11
92 122
3359 37
28 16
648 14
11 269

Sample Output

Sample #1
4 Sample #2
0 Sample #3
17

HINT

​ 2≤N≤10^4

​ 1≤xi,yi≤10^9

Sol

线段树优化建图+2-sat+二分。

首先我们二分答案k,然后把一个点向离他距离为k以内的点的反点连边(2-sat的边表示依赖关系),之后直接判断有没有解,但是显然这样会TLE,因为边的个数是\(n^2\)级别的。

所以考虑线段树优化建图,步骤为:

1.按照2n个点排序,建出线段树,每个点向他的父亲连边,最底层点向这个点代表的点的反点连边(因为2-sat连的是反点,别的题没有必要)

2.对于每个点进行编号(一共2n个)。

3.我们考虑每个点,找到和他距离k以内的点的两段区间,然后用这个点按照线段树区间查找的方式向logn个区间连边。(注意一定要跳过自己对应的点,因为这代表着自己的反点,不能连边)

中间有点细节,要注意一下。

之后就是2-sat的经典应用了。

Code

#include <bits/stdc++.h>
using namespace std;
struct seg{int l,r,id;seg(int l=0,int r=0,int id=0):l(l),r(r),id(id){}}s[500005];
int n,P,Index,L,p[100005][2],dfn[100005],low[100005],in[100005],cnt,bel[100005],b[100005],x[100005],y[100005],X[100005],Y[100005],vis[100005];
pair<int,int>pos[100005];vector<int>e[100005];stack<int>q;
void build(int x,int L,int R)
{
s[x]=seg(L,R,++P);
if(x>>1) e[s[x>>1].id].push_back(s[x].id);
if(L==R){e[s[x].id].push_back(p[pos[L].first][pos[L].second^1]);return;}
int mid=(L+R)>>1;build(x*2,L,mid);build(x*2+1,mid+1,R);
}
void ins(int x,int L,int R,int u)
{
if(L>R) return;
if(s[x].l==L&&s[x].r==R){e[u].push_back(s[x].id);return;}
int mid=(s[x].l+s[x].r)>>1;
if(R<=mid) ins(x*2,L,R,u);else if(L>mid) ins(x*2+1,L,R,u);
else ins(x*2,L,mid,u),ins(x*2+1,mid+1,R,u);
}
void tarjan(int x)
{
dfn[x]=low[x]=++Index;in[x]=1;q.push(x);
for(int i=0;i<e[x].size();i++)
if(!dfn[e[x][i]]) tarjan(e[x][i]),low[x]=min(low[x],low[e[x][i]]);
else if(in[e[x][i]]) low[x]=min(low[x],dfn[e[x][i]]);
if(dfn[x]==low[x]) for(cnt++;;){int now=q.top();q.pop();in[now]=0;bel[now]=cnt;if(now==x) break;}
}
bool chk(int k)
{
P=cnt=Index=0;for(int i=0;i<=n*5;i++) e[i].clear();while(!q.empty()) q.pop();
memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(in,0,sizeof(in));memset(bel,0,sizeof(bel));
for(int i=1;i<=n;i++) p[i][0]=++P,p[i][1]=++P;
build(1,1,L);
for(int i=1;i<=n;i++)
ins(1,upper_bound(b+1,b+L+1,X[i]-k)-b,x[i]-1,p[i][0]),ins(1,x[i]+1,lower_bound(b+1,b+L+1,X[i]+k)-b-1,p[i][0]),
ins(1,upper_bound(b+1,b+L+1,Y[i]-k)-b,y[i]-1,p[i][1]),ins(1,y[i]+1,lower_bound(b+1,b+L+1,Y[i]+k)-b-1,p[i][1]);
for(int i=1;i<=P;i++) if(!dfn[i]) tarjan(i);int ok=1;
for(int i=1;i<=n;i++) if(bel[p[i][0]]==bel[p[i][1]]) ok=0;
return ok;
}
int find(int I,int P,int x)
{
int res,l=1,r=L;
for(int mid=(l+r)>>1;l<=r;mid=(l+r)>>1)
{
if(b[mid]==x&&!vis[mid]) res=mid,r=mid-1;
else if(b[mid]>x) r=mid-1;else l=mid+1;
}
vis[res]=1;pos[res]=make_pair(I,P);return res;
}
int main()
{
scanf("%d",&n);int l=0,r=1e9,ans;
for(int i=1;i<=n;i++) scanf("%d%d",&X[i],&Y[i]),b[++L]=X[i],b[++L]=Y[i];
sort(b+1,b+L+1);
for(int i=1;i<=n;i++) x[i]=find(i,0,X[i]),y[i]=find(i,1,Y[i]);
for(int mid=(l+r)>>1;l<=r;mid=(l+r)>>1) if(chk(mid)) l=mid+1,ans=mid;else r=mid-1;
printf("%d\n",ans);
}

【ARC069F】Flags 2-sat+线段树优化建图+二分的更多相关文章

  1. 2-sat 问题 【例题 Flags(2-sat+线段树优化建图)】

    序: 模拟赛考了一道 2-sat 问题.之前从来没听过…… 考完才发现其实这个东东只要一个小小的 tarjan 求强连通分量就搞定了. 这个方法真是巧妙啊,拿来讲讲. What is it? [・_・ ...

  2. BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan

    Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...

  3. 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流

    [BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...

  4. 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序

    题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆.  现在 ...

  5. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

  6. 【BZOJ4276】[ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流

    [BZOJ4276][ONTAK2015]Bajtman i Okrągły Robin Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2 ...

  7. 【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra

    题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a, ...

  8. 【bzoj4383】[POI2015]Pustynia 线段树优化建图+差分约束系统+拓扑排序

    题目描述 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r- ...

  9. BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流

    BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流 Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1 ...

随机推荐

  1. selenium 对浏览器的操控 java

    driver.navigate().back();     后退 driver.navigate().forward();   前进 driver.navigate().refresh();    刷 ...

  2. 什么是jsonp?——使用jsonp解决跨域请求问题

    我们在使用ajax请求的时候经常会产生跨域问题,这是由于浏览器的同源策略导致的.所谓同源,即域名.协议.端口均相同,否则不管是静态页面还是动态网页或者web服务都无法通过ajax正常请求.有时候,我们 ...

  3. windows 进程监控 Procmon.exe

    windows 进程监控 Procmon.exe window下一个程序打开太慢,可以用此程序监控.在哪一步慢了,读取文件还是注册表. ProcessMonitor3.2 Process Monito ...

  4. REST的含义和RESTful架构入门

    REST的含义和RESTful架构入门 提纲 1.REST架构的作用 2.REST和RESTful 3.REST的具体含义 3.1 资源实体 3.2 资源实体的表现层 3.3. 资源实体某一变现层的状 ...

  5. 前端xss攻击

    xss是什么 xss跨站脚本攻击(Cross Site Scripting),是一种经常出现在web应用中的计算机安全漏洞,它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌 ...

  6. less使用变量实现Url的前缀

    @url-prefix: "../../../../../Skin/Template/Default"; .test { background: url("@{url-p ...

  7. 【HDU6026】Deleting Edges

    题意 有一个n个节点的无向图,结点编号从0-n-1,每条边的长度时1to9的一个正整数.现在要删除一些边(或者不删),使得到的新图满足下面两个要求. 1.新图是一颗树有n-1条边2.对于每个结点v(0 ...

  8. 【bzoj2144】跳跳棋

    2144: 跳跳棋 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 492  Solved: 244[Submit][Status][Discuss] ...

  9. Codeforces 1142D Foreigner (DP)

    题意:首先定义了一种类数(标志数) 1:1到9都是标志数. 2:若x / 10是标志数,假设x /10在标志数中的排名是k, 若x的个位数小于k % 11, 那么x也是标志数. 现在给你一个字符串,问 ...

  10. SpringBoot27 JDK动态代理详解、获取指定的类类型、动态注册Bean、接口调用框架

    1 JDK动态代理详解 静态代理.JDK动态代理.Cglib动态代理的简单实现方式和区别请参见我的另外一篇博文. 1.1 JDK代理的基本步骤 >通过实现InvocationHandler接口来 ...