【JOI2017春季合宿】Port Facility
题解
思路和\(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的更多相关文章
- UOJ356 [JOI2017春季合宿] Port Facility 【启发式合并】【堆】【并查集】
题目分析: 好像跑得很快,似乎我是第一个启发式合并的. 把玩具看成区间.首先很显然如果有两个玩具的进出时间有$l1<l2<r1<r2$的关系,那么这两个玩具一定在不同的栈中间. 现在 ...
- [JOI2017春季合宿]Port Facility[set、二分图]
题意 你有两个栈,有 \(n\) 个货物,每个货物有一个进栈时间和出栈时间(所有时间的并集是1~2n),问有多少种不同的入栈方案. \(n\le 10^6\) 分析 把每个货物的存在看成区间,相交的区 ...
- UOJ #356. 【JOI2017春季合宿】Port Facility
Description 小M有两个本质不同的栈. 无聊的小M找来了n个玩具.之后小M把这n个玩具随机顺序加入某一个栈或把他们弹出. 现在小M告诉你每个玩具的入栈和出栈时间,现在她想考考小S,有多少种方 ...
- UOJ356 【JOI2017春季合宿】Port Facility
暴力就是O(n^2)连边,二分图,这样只有22分. 我们考虑优化建边,我们按照左端点排序,对于一个新加进来的线段,我们向左端点距其最近的和他相交的线段连边,别的相交的我们连同色边,当一个点连了两条同色 ...
- UOJ #357. 【JOI2017春季合宿】Sparklers
Description 小S和小M去看花火大会. 一共有 n 个人按顺序排成一排,每个人手上有一个仅能被点燃一次的烟花.最开始时第 K 个人手上的烟花是点燃的. 烟花最多能燃烧 T 时间.每当两个人的 ...
- JOI2017 春季合宿:Railway Trip
自己的AC做法似乎离正解偏了十万八千里而且复杂了不少--不管怎样还是记录下来吧. 题意: 题目链接: JOISC2017 F - AtCoder JOISC2017 F - LOJ \(N\)个车站排 ...
- BZOJ 4388 [JOI2012春季合宿]Invitation (线段树、二叉堆、最小生成树)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4388 题解 模拟Prim算法? 原题所述的过程就是Prim算法求最大生成树的过程.于是我 ...
- BZOJ 4221 [JOI2012春季合宿]Kangaroo (DP)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4221 题解 orz WYC 爆切神仙DP 首先将所有袋鼠按大小排序.考虑从前往后DP, ...
- LOJ #2731 [JOI2016春季合宿]Solitaire (DP、组合计数)
题目链接 https://loj.ac/problem/2731 题解 首先一个很自然的思路是,设\(dp[i][j]\)表示选了前\(i\)列,第\(2\)行第\(i\)列的格子是第\(j\)个被填 ...
随机推荐
- linux/linux学习笔记-vim文本编辑器(mooc)
vim文本编辑器 vim与vi的区别:( vim=vi +IMproved) VIM是一个Unix以及类unix文本编辑器 特点:功能强大,高度可定制 vim编辑器的三种模式:一般模式.编辑模式和命令 ...
- 根据select的option文本选中对应的选项
function selectByOptionTxt(obj,txt){ var optionArr = $(obj).find("option"); for(var i=0;i& ...
- Python内置函数compile
英文文档: compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) Compile the source i ...
- PL/SQL基本操作
1.常规过程化形式 declare o_booking_flag ); begin -- Call the procedure destine_ticket(', , 'E', , o_booking ...
- Windows系统里Oracle 11g R2 Client(64bit)的下载与安装
环境: windows10系统(64位) 最好先安装jre或jdk(此软件用来打开oracle自带的可视化操作界面,不装也没关系:可以安装plsql,或者直接用命令行操作) Oracle 11g 是仅 ...
- 03: 使用docker搭建Harbor私有镜像仓库
1.1 harbor介绍 1.Harbor简介 1. Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器. 2. 镜像的存储harbor使用的是官方的docker regi ...
- APP元素定位工具weditor
github地址https://github.com/openatx/weditor python -m weditor --shortcut adb devices 在页面上输入手机设备号,点Con ...
- ffmpeg 常用命令汇总
最近工作常用到ffmpeg 做一些视频数据的处理转换等,用来做测试,今天总结了一下,并参考了网上一些部分朋友的经验,一起在这里汇总了一下,有需要的朋友可以收藏测试一下,有问题可以回帖交流. 1.ffm ...
- Linux 设置定时清除buff/cache的脚本
Linux 设置定时清除buff/cache的脚本 查看内存缓存状态 [root@heyong ~]# free -m total used free shared buff/cache availa ...
- c++ Socket客户端和服务端示例版本三(多线程版本)
客户端 #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/soc ...