zoukankan      html  css  js  c++  java
  • 【ARC069D】Flags

    题目大意

    Snuke 将 (N) 个标志放在一条线上。

    (i) 个标志可以放置在坐标 (x_i) 或坐标 (y_i)上。

    Snuke 认为当他们中的两个之间的最小距离 (d) 更大时,标志看起来更好。找出 (d) 的最大可能值。

    题解

    二分最小值,然后用 2-SAT check

    具体是给出的点对 ((a,b)) 是满足 (alor b)( eg a lor eg b)

    然后距离小于 mid 的点对 ((a,b)) 满足 ( eg a lor eg b)

    然后对所有点排序,距离小于 mid 的点对建边时用线段树优化加边

    //I am hunting for the golden stag.
    #include <algorithm>
    #include <vector>
    #include <cstdio>
    #include <stack>
    #define opp(x) (x+cnt)
    using namespace std;
    const int maxn = 1e5 + 10;
    int n,node,tot,cnt,scccnt,rt_in,rt_out,x[maxn],y[maxn],scc[maxn<<4],low[maxn<<4],dfn[maxn<<4],ls[maxn<<4],rs[maxn<<4];
    pair<int,int> p[maxn];
    stack<int> s; bool vis[maxn<<4];
    vector<int> edge[maxn<<4];
    inline void build_in(int l,int r,int& root) {
    	if (l == r) return void(root = l);
    	root = ++node;
    	int mid = l+r>>1;
    	build_in(l,mid,ls[root]);
    	build_in(mid+1,r,rs[root]);
    	edge[ls[root]].push_back(root);
    	edge[rs[root]].push_back(root);
    }
    inline void build_out(int l,int r,int& root) {
    	if (l == r) return void(root = l);
    	root = ++node;
    	int mid = l+r>>1;
    	build_out(l,mid,ls[root]);
    	build_out(mid+1,r,rs[root]);
    	edge[root].push_back(ls[root]);
    	edge[root].push_back(rs[root]);
    }
    inline void update_in(int l,int r,int u,int vl,int vr,int root) {
    	if (l > vr || r < vl) return;
    	if (vl <= l && r <= vr) return void(edge[root].push_back(u));
    	int mid = l+r>>1;
    	update_in(l,mid,u,vl,vr,ls[root]);
    	update_in(mid+1,r,u,vl,vr,rs[root]);
    }
    inline void update_out(int l,int r,int u,int vl,int vr,int root) {
    	if (l > vr || r < vl) return;
    	if (vl <= l && r <= vr) return void(edge[u].push_back(root));
    	int mid = l+r>>1;
    	update_out(l,mid,u,vl,vr,ls[root]);
    	update_out(mid+1,r,u,vl,vr,rs[root]);
    }
    inline void tarjan(int now) {
    	dfn[now] = low[now] = ++tot;
    	s.push(now); vis[now] = true;
    	for (size_t i = 0;i < edge[now].size();i++) {
    		int to = edge[now][i];
    		if (!dfn[to]) {
    			tarjan(to);
    			low[now] = min(low[now],low[to]);
    		} else if (vis[to]) low[now] = min(low[now],dfn[to]);
    	}
    	if (low[now] == dfn[now]) {
    		for (scccnt++;s.top() ^ now;vis[s.top()] = false,s.pop()) scc[s.top()] = scccnt;
    		scc[s.top()] = scccnt;
    		vis[s.top()] = false,s.pop();
    	}
    }
    inline bool check(int mid) {
    	for (int i = 1;i <= cnt*16;i++) { dfn[i] = low[i] = scc[i] = vis[i] = 0; edge[i].clear(); }
    	for (int i = 1;i <= cnt*16;i++) ls[i] = rs[i] = 0;
    	for (;s.size();s.pop());
    	tot = scccnt = 0; node = cnt+cnt;
    	build_in(1,cnt+cnt,rt_in);
    	build_out(1,cnt+cnt,rt_out);
    	for (int i = 1,u,v;i <= n;i++) {
    		u = lower_bound(p+1,p+cnt+1,make_pair(x[i],i))-p;
    		v = lower_bound(p+1,p+cnt+1,make_pair(y[i],i+n))-p;
    		if (u ^ v) {
    			edge[u].push_back(opp(v));
    			edge[v].push_back(opp(u));
    			edge[opp(u)].push_back(v);
    			edge[opp(v)].push_back(u);
    		}
    	}
    	for (int i = 1,u,v;i <= cnt;i++) {
    		u = upper_bound(p+1,p+cnt+1,make_pair(p[i].first-mid,999999999))-p;
    		v = upper_bound(p+1,p+cnt+1,make_pair(p[i].first+mid-1,0))-p-1;
    		if (u < i) {
    			update_in(1,cnt+cnt,opp(i),u,i-1,rt_in);
    			update_out(1,cnt+cnt,i,opp(u),opp(i-1),rt_out);
    		}
    		if (v > i) {
    			update_in(1,cnt+cnt,opp(i),i+1,v,rt_in);
    			update_out(1,cnt+cnt,i,opp(i+1),opp(v),rt_out);
    		}
    	}
    	for (int i = 1;i <= cnt+cnt;i++) if (!dfn[i]) tarjan(i);
    	for (int i = 1;i <= cnt;i++) if (scc[i] == scc[opp(i)]) return false;
    	return true;
    }
    inline int solve() {
    	int l(0),r(1e9),mid,ans(0);
    	for (;l <= r;check(mid = l+r>>1) ? ans = mid,l = mid+1 : r = mid-1);
    	return ans;
    }
    int main() {
    	scanf("%d",&n);
    	for (int i = 1;i <= n;i++) {
    		scanf("%d%d",&x[i],&y[i]);
    		p[i] = make_pair(x[i],i); p[i+n] = make_pair(y[i],i+n);
    	}
    	cnt = n+n;
    	sort(p+1,p+n+n+1);
    	printf("%d",solve());
    	return 0;
    }
    
  • 相关阅读:
    288 Node.js模块化开发:js开发弊端,模块的概念,模块成员导出的2种方式及其区别,模块成员导入
    287 Node.js快速入门:Node.js 的组成,Node.js基础语法,Node.js全局对象global
    286 Node开发概述,Node运行环境搭建以及安装失败解决办法
    285 H5 Web Workers
    使用nvm安装nodejs
    函数式 UI:Web开发终于摆脱了框架的束缚
    Vue渲染函数
    微信小程序使用canvas实现生成海报图的功能
    Vue中插槽指令
    Vue之nextTick原理
  • 原文地址:https://www.cnblogs.com/lrj124/p/13894880.html
Copyright © 2011-2022 走看看