http://uoj.ac/problem/356

题解

思路和\(NOIP\)双栈排序差不多。

对于两个元素,若\(l_1<l_2<r_1<r_2\)那么它们不能在一个栈里,我们连一条边。

若最后的这张图是二分图,那么答案就是\(2^{联通块个数}\)。

这道题就是要我们优化连边。

我们把所有线段按照左端点排序,然后我们用平衡树按照右端点为关键字维护已经扫描过去的线段。

发现要和当前扫描到的线段连边的是平衡树上\(dfs\)序连续的一段区间。

考虑这个边怎么连。

我们只需要在这个区间的右端点处和这个点连上1的边,中间连0边就行了。

所以我们可以用并查集的思想,只和右端点连边,在维护一个连0边的\(set\),如果一个点和两边都连上0边就删掉它。

代码

#include<bits/stdc++.h>
#define N 2000009
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int inf=1e9;
int pre[N],nxt[N],head[N],tot;
int top,st[N];
int n;
int vis[N];
inline ll rd(){
ll x=0;char c=getchar();bool f=0;
while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f?-x:x;
}
inline void MOD(int &x){x=x>=mod?x-mod:x;}
inline ll power(ll x,ll y){
ll ans=1;
while(y){
if(y&1)ans=ans*x%mod;
x=x*x%mod;y>>=1;
}
return ans;
}
struct edge{
int n,to,l;
}e[N*6];
inline void add(int u,int v,int l){
if(!u||!v)return;
// cout<<u<<" "<<v<<" "<<l<<endl;
e[++tot].n=head[u];e[tot].to=v;head[u]=tot;e[tot].l=l;
e[++tot].n=head[v];e[tot].to=u;head[v]=tot;e[tot].l=l;
}
struct node{
int l,r;
inline bool operator <(const node &b)const{
if(l!=b.l)return l<b.l;
return r<b.r;
}
}a[N];
struct nd{
int pos,id;
inline bool operator <(const nd &b)const{
return pos<b.pos;
}
};
set<nd>s1,s2;
set<nd>::iterator it;
void dfs(int u){
for(int i=head[u];i;i=e[i].n){
int v=e[i].to;
if(vis[v]&&(vis[u]^e[i].l)!=vis[v]){puts("0");exit(0);}
if(!vis[v]){
vis[v]=vis[u]^e[i].l;
dfs(v);
}
}
}
int main(){
n=rd();
for(int i=1;i<=n;++i)a[i].l=rd(),a[i].r=rd();
sort(a+1,a+n+1);
s1.insert(nd{-inf,0});s1.insert(nd{inf,0});
s2.insert(nd{-inf,0});s2.insert(nd{inf,0});
for(int i=1;i<=n;++i){
it=s1.lower_bound(nd{a[i].r,i});
nxt[i]=it->id;
pre[it->id]=0;
it--;
pre[i]=it->id;
nxt[it->id]=0;
if(it->pos>a[i].l)add(i,it->id,1);
it=s2.lower_bound(nd{a[i].r,i});--it;
while(1){
if(it->pos<a[i].l)break;
if(pre[it->id]&&a[pre[it->id]].r>a[i].l){add(it->id,pre[it->id],0);pre[it->id]=0;}
if(nxt[it->id]&&a[nxt[it->id]].r<a[i].r){add(it->id,nxt[it->id],0);nxt[it->id]=0;}
if(!pre[it->id]&&!nxt[it->id])st[++top]=it->id;
it--;
}
for(int j=1;j<=top;++j)s2.erase(nd{a[st[j]].r,st[j]});
top=0;
s1.insert(nd{a[i].r,i});
s2.insert(nd{a[i].r,i});
}
int ans=1;
for(int i=1;i<=n;++i)if(!vis[i]){
vis[i]=2;
dfs(i);
MOD(ans=ans+ans);
}
printf("%d\n",ans);
return 0;
}

【JOI2017春季合宿】Port Facility的更多相关文章

  1. UOJ356 [JOI2017春季合宿] Port Facility 【启发式合并】【堆】【并查集】

    题目分析: 好像跑得很快,似乎我是第一个启发式合并的. 把玩具看成区间.首先很显然如果有两个玩具的进出时间有$l1<l2<r1<r2$的关系,那么这两个玩具一定在不同的栈中间. 现在 ...

  2. [JOI2017春季合宿]Port Facility[set、二分图]

    题意 你有两个栈,有 \(n\) 个货物,每个货物有一个进栈时间和出栈时间(所有时间的并集是1~2n),问有多少种不同的入栈方案. \(n\le 10^6\) 分析 把每个货物的存在看成区间,相交的区 ...

  3. UOJ #356. 【JOI2017春季合宿】Port Facility

    Description 小M有两个本质不同的栈. 无聊的小M找来了n个玩具.之后小M把这n个玩具随机顺序加入某一个栈或把他们弹出. 现在小M告诉你每个玩具的入栈和出栈时间,现在她想考考小S,有多少种方 ...

  4. UOJ356 【JOI2017春季合宿】Port Facility

    暴力就是O(n^2)连边,二分图,这样只有22分. 我们考虑优化建边,我们按照左端点排序,对于一个新加进来的线段,我们向左端点距其最近的和他相交的线段连边,别的相交的我们连同色边,当一个点连了两条同色 ...

  5. UOJ #357. 【JOI2017春季合宿】Sparklers

    Description 小S和小M去看花火大会. 一共有 n 个人按顺序排成一排,每个人手上有一个仅能被点燃一次的烟花.最开始时第 K 个人手上的烟花是点燃的. 烟花最多能燃烧 T 时间.每当两个人的 ...

  6. JOI2017 春季合宿:Railway Trip

    自己的AC做法似乎离正解偏了十万八千里而且复杂了不少--不管怎样还是记录下来吧. 题意: 题目链接: JOISC2017 F - AtCoder JOISC2017 F - LOJ \(N\)个车站排 ...

  7. BZOJ 4388 [JOI2012春季合宿]Invitation (线段树、二叉堆、最小生成树)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4388 题解 模拟Prim算法? 原题所述的过程就是Prim算法求最大生成树的过程.于是我 ...

  8. BZOJ 4221 [JOI2012春季合宿]Kangaroo (DP)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4221 题解 orz WYC 爆切神仙DP 首先将所有袋鼠按大小排序.考虑从前往后DP, ...

  9. LOJ #2731 [JOI2016春季合宿]Solitaire (DP、组合计数)

    题目链接 https://loj.ac/problem/2731 题解 首先一个很自然的思路是,设\(dp[i][j]\)表示选了前\(i\)列,第\(2\)行第\(i\)列的格子是第\(j\)个被填 ...

随机推荐

  1. 面试题:线程A打印1-10数字,打印到第5个数字时,通知线程B

    此题考查的是线程间的通信方式. 可以利用park/unpark实现 可以利用volatile关键字实现 可以利用synchronized结合wait notify实现 可以利用JUC中的CountDo ...

  2. [DS+Algo] 007 希尔排序及其代码实现

    步骤 将数组列在一个表(一行多列)中,按特定的步长进行插入排序 步长从 length/2 到 1,每次除 2 将数组转换至表是为了更好地理解这算法,算法本身还是使用数组进行排序 算法性能 (根据步长序 ...

  3. VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题

    VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题:https://blog.csdn.net/jerrica/article/d ...

  4. 基于bs4库的HTML标签遍历方法

    基于bs4库的HTML标签遍历方法 import requests r=requests.get('http://python123.io/ws/demo.html') demo=r.text HTM ...

  5. P1067多项式输出

    这道题是2009普及组的题,仍然是一个字符串+模拟.(蒻到先不刷算法) 这道题的题干给了很多的提示,也很全面,但是当我把种种情况都考虑到了后,在写代码的过程中仍然出现了很多的错误,wa了三四次.其实导 ...

  6. CF573E Bear and Bowling

    题目 我们设\(f_{i,j}\)表示前\(i\)个数中选\(j\)个的最大值. 那么显然有\(f_{i,j}=max(f_{i-1,j},f_{i-1,j-1}+j*a_i)\). 这个东西我们首先 ...

  7. git flow 基础了解

    git flow 软件开发中的一个分支管理流程.利用它可以让软件开发有条不紊的进行,先对它进行一个大概的了解吧,后面工作了实际用到了在深入研究一下. 先看下它的工作流程: 这张图看着一脸茫然,先放在这 ...

  8. Bootstrap前端框架快速入门专题

    1.Bootstrap简介 Bootstrap,出自自 Twitter,是目前最受欢迎的前端框架. Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的前端框架,它简洁灵活,使得 W ...

  9. 用eclipse怎么打war包?

    用eclipse怎么打war包? 在服务器上部署很多都是用war包进行部署的,eclipse是很友好的支持把java项目打成war包的,下面就把打war的经验写出来,供大家参考 百度经验:jingya ...

  10. python 查询Neo4j多节点的多层关系

    需求:查询出满足3人及3案有关系的集合 # -*- coding: utf-8 -*- from py2neo import Graph import psycopg2 # 二维数组查找 def fi ...