博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
codeforces 872E. Points, Lines and Ready-made Titles
阅读量:6497 次
发布时间:2019-06-24

本文共 3065 字,大约阅读时间需要 10 分钟。

 

E. Points, Lines and Ready-made Titles
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given n distinct points on a plane with integral coordinates. For each point you can either draw a vertical line through it, draw a horizontal line through it, or do nothing.

You consider several coinciding straight lines as a single one. How many distinct pictures you can get? Print the answer modulo 109 + 7.

Input

The first line contains single integer n (1 ≤ n ≤ 105) — the number of points.

n lines follow. The (i + 1)-th of these lines contains two integers xiyi ( - 109 ≤ xi, yi ≤ 109) — coordinates of the i-th point.

It is guaranteed that all points are distinct.

Output

Print the number of possible distinct pictures modulo 109 + 7.

Examples
input
4 1 1 1 2 2 1 2 2
output
16
input
2 -1 -1 0 1
output
9
Note

In the first example there are two vertical and two horizontal lines passing through the points. You can get pictures with any subset of these lines. For example, you can get the picture containing all four lines in two ways (each segment represents a line containing it).

The first way:
The second way:

In the second example you can work with two points independently. The number of pictures is 32 = 9.

 

 题意:

给出二维平面上的n个点,每个点可以画一条水平线,也可以画一条竖直线,也可以什么都不画

求 图案 方案数

 

思路:把冲突的点放到一个连通块中,对每个连通块单独处理,乘法原理计数

 

对于一个连通块来说,n个点最多有n+1条边

最开始一个点有2条边,然后每加入一条边,都要加入一个点

当然,可以只加点不加边(例:井字形)

所以 边数E<=点数P+1

 

因为连通块里加入的这些边,保证不冲突

所以

 

1、E==P+1

因为一个点只能连一条边,所以这个连通块最多只能有P条边

所以这个连通块的方案数=C(E,1)+C(E,2)+……+ C(E,P)= 2^E-1 

2、E<=P

方案数=C(E,1)+C(E,2)+……+C(E,E)= 2^E

 

#include
#include
#include
#define N 100001using namespace std;const int mod=1e9+7;int hasx[N],hasy[N],x[N],y[N];int fa[N*2];int sizp[N],size[N*2];void read(int &x){ x=0; int f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } x*=f;}int find(int i) { return fa[i]==i ? i : fa[i]=find(fa[i]); }int Pow(int a,int b){ int res=1; for(;b;a=1ll*a*a%mod,b>>=1) if(b&1) res=1ll*res*a%mod; return res;}int main(){ int n; read(n); for(int i=1;i<=n;i++) read(x[i]),read(y[i]),hasx[i]=x[i],hasy[i]=y[i]; sort(hasx+1,hasx+n+1); sort(hasy+1,hasy+n+1); int tot1=unique(hasx+1,hasx+n+1)-hasx-1,cnt=tot1; for(int i=1;i<=n;i++) x[i]=lower_bound(hasx+1,hasx+tot1+1,x[i])-hasx; int tot2=unique(hasy+1,hasy+n+1)-hasy-1; cnt+=tot2; for(int i=1;i<=n;i++) y[i]=lower_bound(hasy+1,hasy+tot2+1,y[i])-hasy; for(int i=1;i<=cnt;i++) fa[i]=i; for(int i=1;i<=n;i++) fa[find(x[i])]=find(y[i]+tot1); for(int i=1;i<=n;i++) sizp[find(x[i])]++; for(int i=1;i<=cnt;i++) size[find(i)]++; int ans=1; for(int i=1;i<=cnt;i++) if(find(i)==i) { if(sizp[i]+1==size[i]) ans=1ll*ans*(Pow(2,size[i])+mod-1)%mod; else ans=1ll*ans*Pow(2,size[i])%mod; } printf("%d",ans);}

 

 

转载于:https://www.cnblogs.com/TheRoadToTheGold/p/7711401.html

你可能感兴趣的文章
Android中对Log日志文件的分析[转]
查看>>
舆情,文本挖掘
查看>>
dapper的增、删、查改的CodeSmith模板
查看>>
qt 拖拽 修改大小(二)
查看>>
DTRACE 专家
查看>>
mac os x常用快捷键及用法
查看>>
ASM 图解
查看>>
Minix
查看>>
CentOS 6.5 下Vim 配置图解
查看>>
查看CentOS的网络带宽出口
查看>>
MD5与Base64的思考
查看>>
如何独立开发一个网络请求框架
查看>>
HTMLDOM中三种元素节点、属性节点、文本节点的测试案例
查看>>
js构造函数式编程
查看>>
css构造文本
查看>>
hibernate用注解(annotation)配置sequence
查看>>
仿桌面通知pnotify插件
查看>>
how tomcat works 总结 二
查看>>
Remove Duplicates from Sorted Array II -- LeetCode
查看>>
active mq 配置
查看>>