Codeforces Round #672 (Div. 2) D. Rescue Nibel! ###K ###K //K
题目链接:https://codeforces.ml/contest/1420/problem/D
题意:给定n个灯, 持续开的时间未l~r 问某一时间打开的灯有k盏的组合数
思路:区间重叠问题,考虑扫描线, 把所有的点 左端点标记0 右端点标记1 按左端点升序排序 注意 如果v相同要先放
左端点,然后每次找到右端点的时候 就考虑 当前右端点的这条线段必选, 那么剩下的num-1条里面选k-1 条
这样就能保证每条线段不会被后面的重复选择,只会选择前面的
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define pb push_back 5 const int maxn =3e5+10; 6 const int mod=998244353; 7 ll fac[maxn]; 8 ll inv[maxn]; 9 10 struct ac 11 { 12 int v,f; 13 bool operator<(ac a) 14 { 15 if(a.v==v) return f<a.f; 16 return v<a.v; 17 } 18 }; 19 ac a[maxn*2]; 20 21 22 ll power(ll base,ll n) 23 { 24 ll r=1; 25 while(n) 26 { 27 if(n%2) r=r*base%mod; 28 base=base*base%mod; 29 n/=2; 30 } 31 return r; 32 } 33 34 void init() 35 { 36 fac[0]=1; 37 for(int i=1;i<maxn;i++) 38 fac[i]=fac[i-1]*i%mod; 39 inv[maxn-1]=power(fac[maxn-1],mod-2); 40 for(int i=maxn-2;i>=0;i--) 41 { 42 inv[i]=inv[i+1]*(i+1)%mod; 43 } 44 45 } 46 47 48 ll C(ll m,ll n) 49 { 50 return fac[n]*inv[m]%mod*inv[n-m]%mod; 51 } 52 53 int main() 54 { 55 ios::sync_with_stdio(false); 56 cin.tie(0); 57 int n,k; 58 cin>>n>>k; 59 init(); 60 //cout<<C(3,5)<<'\n'; 61 ll ans=0; 62 int num=0; 63 int tot=0; 64 for(int i=1;i<=n;i++) 65 { 66 int l,r; 67 cin>>l>>r; 68 a[++tot].v=l; 69 a[tot].f=0; 70 a[++tot].v=r; 71 a[tot].f=1; 72 } 73 sort(a+1,a+1+tot); 74 for(int i=1;i<=tot;i++) 75 { 76 if(a[i].f==0) 77 { 78 num++; 79 } 80 else 81 { 82 if(num-1>=k-1) ans+=C(k-1,num-1),ans%=mod; 83 num--; 84 } 85 } 86 cout<<ans<<'\n'; 87 88 89 90 91 }

浙公网安备 33010602011771号