zoukankan      html  css  js  c++  java
  • codeforces 872E. Points, Lines and Ready-made Titles

    http://codeforces.com/contest/872/problem/E

    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<cstdio>
    #include<iostream>
    #include<algorithm>
    
    #define N 100001
    
    using 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);
    }
  • 相关阅读:
    gcc数据对齐之: howto 2.
    gcc数据对齐之: howto 1.
    gcc数据结构对齐之:why.
    linux tricks 之 BUILD_BUG_ON_ZERO.
    linux tricks 之 FIELD_SIZEOF.
    linux tricks 之 container_of.
    linux tricks 之 bitmap分析.
    linux tricks 之 roundup.
    Windows之svn问题
    Embeded linux之地址映射
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7711401.html
Copyright © 2011-2022 走看看