Description

放假啦!
小林和康娜来到了港口,看到有货船正在卸货。
港口十分狭窄,只有两个卸货区可以使用。每个卸货区上面可以堆积任意多个箱子。
每卸下来一个箱子,工作人员都会把这个箱子放在某个卸货区的顶端。之后,当车辆来运走这个箱子的时候,也必须保证这个箱子在某个卸货区的顶端。
港口今天一共运来了N个箱子,第i个箱子在时刻Ai被卸货,在时刻Bi被取走。康娜发现,每个箱子被取走时,都恰好位于所在卸货区的顶端。
康娜觉得很有意思,她想要知道,有多少种卸货方案,使得每个箱子在被取走时都位于所在卸货区的顶端呢?
两种方案不同,当且仅当存在一个箱子,使得在两个方案中这个箱子被放在了不同的卸货区。

Input

第一行一个正整数N,表示箱子的数量。
接下来N行,每行两个空格分割的正整数Ai和Bi,表示第i个箱子在时刻Ai被卸货,在时刻Bi被取走。

Output

输出一行一个非负整数,表示合法的卸货方案。由于这个数字可能过大,你只需要输出方案数对1,000,000,007的模数即可。

Sample Input

4

1 3

2 5

4 8

6 7

Sample Output

4

HINT

对于10%的数据,N<=20
对于30%的数据,N<=2000
对于100%的数据,
1<=N<=10^5
1<=Ai<Bi<=2N
A1,A2,...,AN,B1,B2,...,BN构成1...2N的一个排列。
 
题解:
如果两个物品i,j不能放在一个卸货区上(即 a[i]<a[j]<b[i]<b[j] or a[j]<a[i]<b[j]<b[i]),则记为i与j冲突,在i与j之间连一条边。
这样建出了一个无向图,若其能二分图染色,则存在方案,为2^(连通块个数)。
如果暴力建图,则复杂度为O(n^2),不可行。
考虑用带权并查集,每个点支持查询祖先以及其与祖先染色是否相同,就可以维护连通块了。
现在的问题是如何去掉重复意义的边。
我们可以用线段树套vector来维护右端点在[l,r]之间的物品。这些物品代表的是其所属的并查集以及其在并查集中的染色。若某个vector中的两个物品代表的意义相同,则可以只留一个。
我们把物品按照左端点排序,按顺序插入线段树,则前i-1个物品中,右端点在[a[i]+1,b[i]-1]的物品都与物品i冲突。
这些物品可以在线段树区间[a[i]+1,b[i]-1]中查询得到。我们把这些物品以及物品i所代表的并查集合在一起。
若有两个物品代表的并查集相同,但是染色不同,则发生冲突,不可二分图染色,输出0。
然后,我们清空区间[a[i]+1,b[i]-1]所用到的线段树节点的vector(这些物品现在都代表同一个并查集),根据清空前其中的物品代表的染色,最多重新放入两个。
最后,我们在包含b[i]的线段树节点的vector中放入物品i。
最后,输出ans=2^(并查集个数)。
 
代码:
 #include<bits/stdc++.h>
using namespace std;
vector <int> v[];
int t[][],n,fa[][],bo[][],cnt,nn,tot,now;
pair <int,int> a[],b[];
void build(int l,int r,int fa)
{
cnt++; int x=cnt; t[x][]=l; t[x][]=r;
if(t[x][]==t[fa][])t[fa][]=x;else t[fa][]=x;
if(l==r)return;
build(l,(l+r)/,x); build((l+r)/+,r,x);
}
int get2(int x);
int get1(int x)
{
if(fa[x][]!=x){ int a=fa[x][]; fa[x][]=get1(a); fa[x][]^=get2(a); }
return fa[x][];
}
int get2(int x)
{
if(fa[x][]!=x){ int a=fa[x][]; fa[x][]=get1(a); fa[x][]^=get2(a); }
return fa[x][];
}
void ss(int x,int l,int r)
{
if(l>r)return;
int ll=t[x][],rr=t[x][]; int mid=(ll+rr)/;
if((ll==l)and(rr==r))
{
int mm=v[x].size();
for(int i=;i<mm;i++)
{
int aa=get1(v[x][i]),bb=get2(v[x][i]); int xxx=v[x][i];
if(bo[aa][bb]==){ bo[aa][bb]=; nn++; b[nn]=make_pair(aa,bb); }
}
return;
}
if(r<=mid)ss(t[x][],l,r);else
if(l>mid)ss(t[x][],l,r);else
{ ss(t[x][],l,mid); ss(t[x][],mid+,r); }
}
void ss2(int x,int l,int r)
{
if(l>r)return;
int ll=t[x][],rr=t[x][]; int mid=(ll+rr)/;
if((ll==l)and(rr==r))
{
int mm=v[x].size(),q[]; q[]=; q[]=;
for(int i=;i<mm;i++)
{
int bb=get2(v[x][i]);
if(q[bb]==)q[bb]=v[x][i];
}
v[x].clear();
if(q[]>)v[x].push_back(q[]);
if(q[]>)v[x].push_back(q[]);
return;
}
if(r<=mid)ss2(t[x][],l,r);else
if(l>mid)ss2(t[x][],l,r);else
{ ss2(t[x][],l,mid); ss2(t[x][],mid+,r); }
}
void ss3(int x,int l,int y)
{
int ll=t[x][],rr=t[x][]; int mid=(ll+rr)/;
v[x].push_back(y); if(ll==rr)return;
if(l<=mid)ss3(t[x][],l,y);
if(l>mid)ss3(t[x][],l,y);
}
void hb(int x,int y,int z)
{
int a=get1(x); if(a==y)return;
fa[a][]=y; fa[a][]^=z; tot--;
}
int main()
{
freopen("port.in","r",stdin);
freopen("port.out","w",stdout);
scanf("%d",&n); tot=n;
for(int i=;i<=n;i++)scanf("%d%d",&a[i].first,&a[i].second),fa[i][]=i;
sort(a+,a+n+); build(,*n,);
for(int i=;i<=n;i++)
{
nn=; now=i;
ss(,a[i].first+,a[i].second-);
sort(b+,b+nn+);
for(int j=;j<=nn;j++)
{
if((j>)and(b[j].first==b[j-].first)){ printf("0\n"); return ; }
hb(b[j].first,i,b[j].second^); bo[b[j].first][b[j].second]=;
}
ss2(,a[i].first+,a[i].second-);
ss3(,a[i].second,i);
}
long long ans=;
for(int i=;i<=tot;i++)ans=(ans*)%;
printf("%lld\n",ans);
}

JZOJ5146:港湾的更多相关文章

  1. 网络基础 港湾FlexHammer5010交换机镜像端口配置

    港湾FlexHammer5010交换机镜像端口配置 by:授客 QQ:1033553122 1.登陆港湾交换机FlexHammer5010交换机 方法: telent 交换机ip 输入用户名 输入用户 ...

  2. AT2534 港湾設備 (Port Facility)

    洛谷 先膜一下Iscream巨巨 首先我们可以把题目转化为线段覆盖,如果两条线段相交(不算某一条完全在另一条里面的情况),那么这两条线段代表的集装箱就不能放到同一个栈里,我们在它们之间连一条边.如果图 ...

  3. 设计模式之行为类模式大PK

                                        行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...

  4. “风投云涌”:那些被资本看中的IT企业的风光与辛酸

         进入七月份以来,纷享销客获得D轮融资1亿美元,撼动业界,资本与IT联姻令一部分创业者眼红的同时,没有人注意到背后的风险. 科技与资本的结合,是当今经济社会前行的宏大主题.相关统计显示,软件行 ...

  5. 优化MySchool数据库设计之【巅峰对决】

    优化MySchool数据库设计 之独孤九剑 船舶停靠在港湾是很安全的,但这不是造船的目的 By:北大青鸟五道口原玉明老师 1.学习方法: 01.找一本好书 初始阶段不适合,可以放到第二个阶段,看到知识 ...

  6. 微冷的雨Java基础学习手记(一)

    使用Java理解程序逻辑 之凌波微步 船舶停靠在港湾是很安全的,但这不是造船的目的 北大青鸟五道口原玉明老师出品 1.学习方法: 01.找一本好书 初始阶段不适合,可以放到第二个阶段,看到知识点时,要 ...

  7. 微冷的雨ASP.NET MVC之葵花宝典(MVC)

    微冷的雨ASP.NET MVC之葵花宝典 By:微冷的雨 第一章 ASP.NET MVC的请求和处理机制. 在MVC中: 01.所有的请求都要归结到控制器(Controller)上. 02.约定优于配 ...

  8. css样式加载顺序及覆盖顺序深入理解

    注:内容转载 很多的新手朋友们对css样式加载顺序和覆盖顺序的理解有所偏差,下面用示例为大家详细的介绍下,感兴趣的朋友不要错过 { height: 100%; width: 200; position ...

  9. IP地址数据库-ISP运营商列表(2017年1月)

    IP地址数据库  微信号:qqzeng-ip [全球旗舰版][国内精华版][国外拓展版][英文版][掩码版]     http://qqzeng.com 中国大陆:三大基础运营商 中国电信中国联通中国 ...

随机推荐

  1. 【Luogu】【关卡2-13】线性数据结构(2017年10月)【还差一道题】

    任务说明:数组,链表,队列,栈,都是线性结构.巧用这些结构可以做出不少方便的事情. P1996 约瑟夫问题 n个人,排成环形,喊到m的人出列,输出出列顺序. 咳咳,这个题目不好写,尽管简单就是模拟题. ...

  2. 从 Server Timing Header 看服务器是如何处理请求的

    原文作者:Florian Hämmerle      译者:UC 国际研发 Jothy   写在最前:欢迎你来到“UC国际技术”公众号,我们将为大家提供与客户端.服务端.算法.测试.数据.前端等相关的 ...

  3. Uninstall NetBeans

    There will be a file named uninstall.sh in /usr/local/netbeans-x.x if you installed netbeans with ro ...

  4. 分布式项目web.xml配置文件的表头

    <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://w ...

  5. PHP ftp_nb_fget() 函数

    定义和用法 ftp_nb_fget() 函数从 FTP 服务器上下载一个文件并保存到本地一个已经打开的文件中.(无阻塞) 该函数返回下列值之一: FTP_FAILED(发送/获取失败) FTP_FIN ...

  6. 【Flutter学习】基本组件之基本网格Gradview组件

    一,概述 数据量很大的时用矩阵方式排列比较清晰,此时用网格列表组件,即为GridView组件,可实现多行多列的应用场景. 使用GridView创建网格列表有多种方式: GridView.count 通 ...

  7. Delphi 虚拟桌面

    Delphi创建虚拟桌面实现后台调用外部程序 核心提示:最近在做的一个软件,其中有一部分功能需要调用其它的软件来完成,而那个软件只有可执行文件,根本没有源代码,幸好,我要做的事不难,只需要在我的程序启 ...

  8. AcWing 197. 阶乘分解 (筛法)打卡

    给定整数 N ,试把阶乘 N! 分解质因数,按照算术基本定理的形式输出分解结果中的 pipi 和 cici 即可. 输入格式 一个整数N. 输出格式 N! 分解质因数后的结果,共若干行,每行一对pi, ...

  9. mybatis的核心对象图解

  10. (转)OpenFire源码学习之一:XMPP基础知识

    转:http://blog.csdn.net/huwenfeng_2011/article/details/43412919 前面两张主要讲基础部分.XMPP与Mina有部分抄写于互联网的其他大事 X ...