题意:
解法:
将线段按照l从小到大排序.
从左到右枚举线段,假设当前线段作为选定的k条线段中,l最大的线段,
那么还需要从左边选出k-1条线段,满足这k-1条和e[i].l相交,
计算左边有多少条线段满足e[j].r>=e[i].l,设有cnt条,那么ans+=C(cnt,k-1).
计算cnt可以用树状数组.
code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=2e6+5;
const int mod=998244353;
struct BIT{
int c[maxm];
int lowbit(int i){
return i&-i;
}
void add(int i,int t){
while(i<maxm){
c[i]+=t,i+=lowbit(i);
}
}
int ask(int i){
int ans=0;
while(i){
ans+=c[i],i-=lowbit(i);
}
return ans;
}
}T;
struct E{
int l,r;
}e[maxm];
bool cmp(E a,E b){
return a.l<b.l;
}
int fac[maxm],inv[maxm];
int xx[maxm],num;
int n,k;
int ppow(int a,int b,int mod){
int ans=1%mod;a%=mod;
while(b){
if(b&1)ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
void init(){
fac[0]=1;
for(int i=1;i<maxm;i++)fac[i]=fac[i-1]*i%mod;
inv[maxm-1]=ppow(fac[maxm-1],mod-2,mod);
for(int i=maxm-2;i>=0;i--)inv[i]=(i+1)*inv[i+1]%mod;
}
int C(int n,int m){
if(m<0||m>n)return 0;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
void solve(){
init();
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>e[i].l>>e[i].r;
xx[++num]=e[i].l;
xx[++num]=e[i].r;
}
sort(xx+1,xx+1+num);
num=unique(xx+1,xx+1+num)-xx-1;
for(int i=1;i<=n;i++){
e[i].l=lower_bound(xx+1,xx+1+num,e[i].l)-xx;
e[i].r=lower_bound(xx+1,xx+1+num,e[i].r)-xx;
}
sort(e+1,e+1+n,cmp);
int ans=0;
for(int i=1;i<=n;i++){
int cnt=(i-1)-T.ask(e[i].l-1);
ans=(ans+C(cnt,k-1))%mod;
T.add(e[i].r,1);
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
solve();
return 0;
}