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 }
View Code

 

posted @ 2020-10-19 13:33  canwinfor  阅读(106)  评论(0)    收藏  举报