首页 > 其他 > 详细

Codeforces Round #672 (Div. 2) D. Rescue Nibel! (思维,组合数)

时间:2020-09-26 18:42:45      阅读:44      评论:0      收藏:0      [点我收藏+]

技术分享图片

  • 题意:给你\(n\)个区间,从这\(n\)区间中选\(k\)个区间出来,要求这\(k\)个区间都要相交.问共有多少种情况.

  • 题解:如果\(k\)个区间都要相交,最左边的区间和最右边的区间必须要相交,即\(min(r[1],...,r[k])>=max(l[1],...,l[k])\).我们先按左边界对所有区间进行排序,然后遍历左边界,遍历到某个区间时,说明这个区间的左边界目前是最大的,然后我们再判断当前左边界(\(l[i]\)就是最大的)和集合中右边界(\(rs.begin()\),一定是满足条件的最小右边界)的关系,用组合数(菜鸡不会组合数,直接套的板子qwq)求个和即可.

  • 代码:

    ll f[N],invf[N];
    ll fpow(ll a,ll k){
    	ll res=1;
    	while(k){
    		if(k&1) res=(res*a)%mod;
    		k>>=1;
    		a=a*a%mod;
    		//cout<<1<<endl;
    	}
    	return res;
    }
     
    void init(int n){
    	f[0]=1;
    	for(int i=1;i<=n;++i){
    		f[i]=f[i-1]*i%mod;
    	}
    	invf[n]=fpow(f[n],mod-2);
    	for(int i=n-1;i>=0;--i){
    		invf[i]=invf[i+1]*(i+1)%mod;
    	}
    }
     
     
    ll C(int n,int k){
    	if(k<0 || k>n) return 0;
    	return f[n]*invf[k]%mod*invf[n-k]%mod;
    }
     
    struct misaka{
    	int l,r;
    }e[N];
     
    int t;
    int n,k;
     
    bool cmp(misaka a,misaka b){
    	if(a.l==b.l) return a.r>b.r;
    	return a.l<b.l;
    }
     
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
            init(5e5);
        	cin>>n>>k;
        	for(int i=1;i<=n;++i){
        		cin>>e[i].l>>e[i].r;
        	}
        	sort(e+1,e+1+n,cmp);
        	multiset<int> rs;
        	ll res=0;
        	for(int i=1;i<=n;++i){
        		while(!rs.empty() && *rs.begin()<e[i].l){
        			rs.erase(rs.begin());
        			//cout<<1<<endl;
        		}
        		int cnt=(int)rs.size();
        		res+=C(cnt,k-1)%mod;
        		rs.insert(e[i].r);
        	}
        	cout<<res%mod<<endl;
     
        return 0;
    }
    

Codeforces Round #672 (Div. 2) D. Rescue Nibel! (思维,组合数)

原文:https://www.cnblogs.com/lr599909928/p/13735850.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!