codeforces 361 E - Mike and Geometry Problem

原题:

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

In the first example:

;

;

.

So the answer is 2 + 1 + 2 = 5.

 

提示:数据比较大,需要离散化。可以一段段考虑。

数轴上一段被选取的次数就和几个集合包含它有关了,算组合数。可以直接做出覆盖次数。

 

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
// head
const int N = 2e5+5;
const int MOD = 1e9+7;

int l[N], r[N];
int sum[N*2];
int disc[N*2];
int fac[N];
int n, k;


LL qpow(LL x, LL k)
{
    LL res = 1;
    while(k)
    {
        if(k & 1) res = res * x % MOD;
        x = x * x % MOD;
        k >>= 1;
    }
    return res;
}

LL inv(LL a, LL n)
{
    return qpow(a, n - 2);
}



int C(int n, int m)
{
    if (n < m) return 0;
    return (LL)fac[n] * inv(fac[m], MOD) % MOD * inv(fac[n-m], MOD) % MOD;
}

int main()
{
    //预处理阶乘数
    fac[0] = 1;
    for (int i = 1; i < N; i++)
    {
        fac[i] = ((LL)fac[i-1] * i) % MOD;
    }

    while (scanf("%d%d", &n, &k) == 2)
    {
        int tot = 0;
        for (int i = 0; i < n; i++)
        {
            scanf("%d%d", l+i, r+i);
            disc[tot++] = l[i];
            disc[tot++] = ++r[i];
        }
        sort(disc, disc + tot);
        tot = unique(disc, disc + tot) - disc;

        for (int i = 0; i < n; i++)
        {
            int l = lower_bound(disc, disc + tot, ::l[i]) - disc;
            int r = lower_bound(disc, disc + tot, ::r[i]) - disc;
            sum[l]++;
            sum[r]--;
        }

        int ans = 0;
        for (int i = 1; i < tot; i++)
        {
            sum[i] += sum[i-1];
            ans = (ans + (LL)C(sum[i-1], k) * (disc[i] - disc[i-1])) % MOD;
        }
        printf("%d\n", ans);
        memset(sum, 0, sizeof sum);
    }
    return 0;
}

 

 

posted @ 2016-07-13 10:45  Shawn_Ji  阅读(149)  评论(0编辑  收藏  举报