假如每个点被n1条线段覆盖求k个线段覆盖它的方案数 显然C(n1,k)
点太多那就离散化以线段的形式来求最多20万条线段求覆盖线段数更合理
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#define mod 1000000007ll
#define LL long long
#define maxn 200010
using namespace std;
struct node{
LL l,r;
}no[maxn];
LL d[2*maxn],f[maxn],cnt = 0,sum[2*maxn] = {0},n,k;
void init()
{
f[0] = 1;
for(int i=1;i<maxn;i++)
{
f[i] = f[i-1]*(LL)i;
f[i] %= mod;
}
}
LL modPow(LL n,LL m)
{
LL ans = 1;
while(m)
{
if(m&1ll)ans*=n;
ans%=mod;
n*=n;
n%=mod;
m>>=1;
}
return ans;
}
LL C(LL n,LL m)
{
return f[n]*modPow(f[m]*f[n-m]%mod,mod-2)%mod;
}
int main()
{
init();
scanf("%I64d %I64d",&n,&k);
for(int i=0;i<n;i++) scanf("%I64d %I64d",&no[i].l,&no[i].r);
for(int i=0;i<n;i++)
{
d[cnt++] = no[i].l;
d[cnt++] = no[i].r+1;
}
sort(d,d+cnt);
cnt = unique(d,d+cnt)-d;
for(int i=0;i<n;i++)
{
LL pre = lower_bound(d,d+cnt,no[i].l)-d;
sum[pre]++;
pre = lower_bound(d,d+cnt,no[i].r+1)-d;
sum[pre]--;
}
LL sum1 = sum[0],ans = 0;
for(int i=1;i<cnt;i++)
{
LL temp = 0;
if(sum1>=k) temp = (d[i]-d[i-1])%mod*C(sum1,k)%mod;
ans+=temp;
ans%=mod;
sum1+=sum[i];
}
printf("%I64d\n",ans);
return 0;
}