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;
}
posted @ 2016-07-07 20:09  qscqesze  阅读(484)  评论(0编辑  收藏  举报