【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\)个被填 ...
随机推荐
- 【QT开发】QT在windows下的exe应用程序如何在别人的电脑上直接运行
当你利用QT编译了一个可执行程序,需要将这个可执行程序拷贝到别人的电脑上运行,这个时候除了这个可执行程序外,还需要支持的库才可用运行.一般来说通过下面的方法可以实现. 首先,需要看你用的是什 ...
- Mac020--常用插件
Google浏览器常用插件 1.github插件octotree 2.掘金Chrome网上应用商店 2-1.掘金/老司机的神兵利器 2-2.好用的Google插件:来自掘金 3.Gliffy Diag ...
- 【Python基础】_1 Python简介
1 Python简介 Python是一种计算机程序设计语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大型项 ...
- MySQL数据类型之整型
还一个 Decimal 就是这么创建 查看当前数据表 查看tb1得表得所有记录....
- 2019JAVA第一次课程总结
课程总结:到现在为止之,学习专业课程已有两周了,从刚开始的啥也不懂,现在慢慢入门了.最开始我们为JAVA开发了运行环境,然后使用类编写了最简单的输出,然后开始学习了数据类型,这可以在编程中帮我们解决一 ...
- linux中防止黑客进入单用户模式进行强制修改密码窃取数据
如何防止别人恶意通过单用户系统破解root密码,进入系统窃取数据? 给grub加密,不让别人通过grub进入单用户. 当前系统:CentOS Linux release 7.6.1810 (Core) ...
- Spark Netty 通信框架解析
1.RpcEndpoint: RPC端点 Spark针对每个节点(Client.Master.Worker)都称之为一个RpcEndpoint,且都实现RpcEndpoint接口,内部根据不同端点的需 ...
- Vue 实现手动刷新组件
Vue 实现手动刷新组件:https://www.jianshu.com/p/742142dc95f3
- Linux cd命令(4)
可以说在Linux上的一切操作都是从 cd 命令开始的.cd 是change directory的简写,其作用就是更改当前工作目录. 使用cd 对于这个命令的使用,不用多说了.需要注意的两点就是: c ...
- SpringBoot自定义配置步骤
1. 在yml中填写自定义配置 ly: sms: accessKeyId: # 短信配置 accessKeySecret: signName: xx商城 # 签名名称 verifyCodeTempla ...