zoukankan      html  css  js  c++  java
  • CodeForces 689E Mike and Geometry Problem (离散化+组合数)

    Mike and Geometry Problem

    题目链接:

    http://acm.hust.edu.cn/vjudge/contest/121333#problem/I

    Description

    Mike wants to prepare for IMO but he doesn't know geometry, so his teacher gave him an interesting geometry problem. Let's define f([l, r]) = r - l + 1 to be the number of integer points in the segment [l, r] with l ≤ r (say that ). You are given two integers n and k and n closed intervals [li, ri] on OX axis and you have to find:

    In other words, you should find the sum of the number of integer points in the intersection of any k of the segments.

    As the answer may be very large, output it modulo 1000000007 (109 + 7).

    Mike can't solve this problem so he needs your help. You will help him, won't you?

    Input

    The first line contains two integers n and k (1 ≤ k ≤ n ≤ 200 000) — the number of segments and the number of segments in intersection groups respectively.

    Then n lines follow, the i-th line contains two integers li, ri( - 109 ≤ li ≤ ri ≤ 109), describing i-th segment bounds.

    Output

    Print one integer number — the answer to Mike's problem modulo 1000000007 (109 + 7) in the only line.

    Sample Input

    Input
    3 2
    1 2
    1 3
    2 3
    Output
    5
    Input
    3 3
    1 3
    1 3
    1 3
    Output
    3
    Input
    3 1
    1 2
    2 3
    3 4
    Output
    6

    Hint

    题意:

    横轴上有n个区间,每次取其中的k个区间,记录区间交集所覆盖的整点;
    问对于所有的区间取法,一共覆盖了多少次整点;

    题解:

    实际上先求出每个整点被多少个区间所覆盖;
    假设某点被m条边覆盖,则C(m, k)即为该点一共被覆盖的次数;
    (若 m < k 则说明不可能处于k个区间的交集区);
    前提:离散化各点! Map[l]++; Map[r+1]--;

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #include <map>
    #include <set>
    #include <vector>
    #define LL long long
    #define eps 1e-8
    #define maxn 201000
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define IN freopen("in.txt","r",stdin);
    using namespace std;
    
    int n;
    LL k;
    map<int,int> mp;
    
    LL x,y,gcd;
    void ex_gcd(LL a,LL b)
    {
        if(!b) {x=1;y=0;gcd=a;}
        else {ex_gcd(b,a%b);LL temp=x;x=y;y=temp-a/b*y;}
    }
    LL f1[maxn],f2[maxn];
    /*分子n!,f[i]为(i!)%mod的值*/
    void F1()
    {
        f1[0]=1;
        for(int i=1;i<maxn;i++)
            f1[i]=(f1[i-1]*i)%mod;
    }
    /*分母m!,f[i]为(1/i!)%mod的值--逆元*/
    void F2()
    {
        f2[0]=1;
        for(int i=1;i<maxn;i++)
        {
            ex_gcd(i,mod);while(x<0) {x+=mod;y-=i;}
            f2[i]=(f2[i-1]*(x%mod))%mod;
        }
    }
    LL C_m_n(LL m,LL n)
    {
        /*ans=m!/(m-n)!n!*/
        LL ans=(((f1[m]*f2[m-n])%mod)*f2[n])%mod;
        return ans;
    }
    
    int main(int argc, char const *argv[])
    {
        //IN;
    
        F1(); F2();
        while(scanf("%d %I64d",&n,&k) != EOF)
        {
            mp.clear();
            for(int i=1; i<=n; i++) {
                LL x,y; scanf("%I64d %I64d", &x,&y);
                mp[x]++;
                mp[y+1]--;
            }
    
            LL last = 0;
            LL ans = 0, cur = 0;
            map<int,int>::iterator it;
            for(it=mp.begin(); it!=mp.end(); it++) {
                LL x = it->first, y = it->second;
                if(cur >= k)
                    ans = (ans + C_m_n(cur, k)*(x-last)) % mod;
                last = x;
                cur += y;
            }
    
            printf("%I64d
    ", ans);
        }
    
        return 0;
    }
    
    
  • 相关阅读:
    Mybatis使用map传递参数与模糊查询写法
    mybatis实现简单的crud
    普通maven项目导入mybatis依赖后找不到程序包(已解决)
    MarkDown语法学习
    CentOS 7 配置hadoop(一) 安装虚拟机(伪分布)
    CentOS 7 配置hadoop(二) 配置hdfs(伪分布)
    生成32个的字母加数字
    mysql 横变竖 竖变横
    Java实现短息验证
    spring+springmvc+mybatis+Redis的配置文件
  • 原文地址:https://www.cnblogs.com/Sunshine-tcf/p/5693356.html
Copyright © 2011-2022 走看看