• Codeforces Round #361 (Div. 2) E. Mike and Geometry Problem 离散化 排列组合


    E. Mike and Geometry Problem

    题目连接:

    http://www.codeforces.com/contest/689/problem/E

    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

    3 2
    1 2
    1 3
    2 3

    Sample Output

    5

    Hint

    题意

    给你n个区间,然后让你暴力的C(n,k)选择k个区间,一直选下去

    然后问你这个k个区间求交集之后 ,这个交集的大小累加下来的答案是多少。

    题解

    考虑第i个数,如果被cnt个区间覆盖了,那么他对答案的贡献就是C(cnt,k)

    那么我们把所有操作离散化之后,再O(n)的去扫一遍就好了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5+7;
    const int mod = 1e9+7;
    long long fac[maxn];
    long long qpow(long long a,long long b)
    {
        long long ans=1;a%=mod;
        for(long long i=b;i;i>>=1,a=a*a%mod)
            if(i&1)ans=ans*a%mod;
        return ans;
    }
    long long C(long long n,long long m)
    {
        if(m>n||m<0)return 0;
        long long s1=fac[n],s2=fac[n-m]*fac[m]%mod;
        return s1*qpow(s2,mod-2)%mod;
    }
    int n,k;
    int l[maxn],r[maxn];
    int main()
    {
        fac[0]=1;
        for(int i=1;i<maxn;i++)
            fac[i]=fac[i-1]*i%mod;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){
            scanf("%d",&l[i]);
            scanf("%d",&r[i]);
        }
        vector<pair<int,int> >op;
        for(int i=1;i<=n;i++){
            op.push_back(make_pair(l[i]-1,1));
            op.push_back(make_pair(r[i],-1));
        }
        sort(op.begin(),op.end());
        long long ans = 0;
        int cnt=0;
        int la=-2e9;
        for(int i=0;i<op.size();i++){
            ans=(ans+C(cnt,k)*(op[i].first-la))%mod;
            la=op[i].first;
            cnt+=op[i].second;
        }
        cout<<ans<<endl;
    }
  • 相关阅读:
    集合的遍历和扩容原理
    最新鲜最详细的Android SDK下载安装及配置教程
    开启IIS Express可以调试X64项目
    C# 正则表达式大全
    Windows下SQLMAP的安装图解
    当前比较流行的前端框架2
    前端组件库1
    服务器Windows 登录 出现401 错误
    IPV6配置
    implicit和 explicit关键字
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5651446.html
Copyright © 2020-2023  润新知