D. Rescue Nibel!(排序&组合数学)

    科技2022-07-21  102

    D. Rescue Nibel!(排序&组合数学)

    思路:排序 + + +组合数学

    利用差分思想,将区间按左端点排序,左端点值为1,右端点值为-1,这样 便于统计相交区间数量。

    然后对每个区间,求出在它之前与它相交的区间个数 c n t cnt cnt

    它的贡献即为: C ( c n t , k − 1 ) C(cnt,k-1) C(cnt,k1)

    当区间端点重合时,优先用值为1的,这样不会少统计。

    每遍历完一个区间后, c n t + = i . s e c o n d cnt+=i.second cnt+=i.second,表示还剩多少个相交区间。

    #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=998244353; #define mst(a,b) memset(a,b,sizeof a) #define lx x<<1 #define rx x<<1|1 #define reg register #define PII pair<int,int> #define fi first #define se second #define pb push_back #define il inline int n,k; vector<PII>ans; bool cmp(PII a,PII b){ return a.fi==b.fi?a.se>b.se:a.fi<b.fi; } ll ksm(ll a,ll n){ ll ans=1; while(n){ if(n&1) ans=ans*a%mod; a=a*a%mod; n>>=1; } return ans; } ll fac[N]; ll C(ll n,ll m){ if(n<m) return 0; return fac[n]*ksm(fac[m],mod-2)%mod*ksm(fac[n-m],mod-2)%mod; } int main(){ scanf("%d%d",&n,&k);fac[0]=1; for(int i=1,l,r;i<=n;i++){ scanf("%d%d",&l,&r); ans.pb({l,1}),ans.pb({r,-1}); fac[i]=fac[i-1]*i%mod; } sort(ans.begin(),ans.end(),cmp); ll res=0,cnt=0; for(auto i:ans){ if(i.se==1) res=(res+C(cnt,k-1))%mod; cnt+=i.se; } printf("%lld\n",res); return 0; }
    Processed: 0.011, SQL: 8