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);
    }
  • 相关阅读:
    ORACLE11G 字符集更改(这里更改为AL32UTF8)
    linux 安装jdk1.8
    oracle的 listagg() WITHIN GROUP ()函数使用
    数据库事务中的隔离级别和锁以及spring @Transactional注解参数详解
    java读取Oracle中大字段数据(CLOB)的方法
    oracle常用函数_时间
    案例-todolist计划列表【添加计划】
    案例-todolist计划列表【显示列表】
    案例-todolist计划列表[基本代码]
    vue 阻止元素的默认行为
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7711401.html
Copyright © 2011-2022 走看看