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
3 2
1 2
1 3
2 3
5
3 3
1 3
1 3
1 3
3
3 1
1 2
2 3
3 4
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; }