码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #678 (Div. 2) C. Binary Search (二分,组合数)

时间:2020-10-27 11:38:34      阅读:29      评论:0      收藏:0      [点我收藏+]

标签:二分查找   alt   mic   题解   span   arc   构造   oid   技术   

技术图片

  • 题意:有长度\(n\)的序列,让你构造序列,使得二分查找能在\(pos\)位置找到值\(x\).问最多能构造出多少种排列?

  • 题解:题目给出的\(pos\)是固定的,所以我们可以根据图中所给的代码来进行二分,确定有多少数小于\(x\)和大于\(x\),然后根据排列组合即可算出答案.

  • 代码:

    int n,x,pos;
    ll fac[N];
    
    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;
    }
    
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        cin>>n>>x>>pos;
        init(n);
    
        int l=0,r=n;
        int L=0,R=0;
        while(l<r){
            int mid=(l+r)>>1;
            if(mid<=pos){
                if(mid!=pos) L++;
                l=mid+1;
            }
            else R++,r=mid;
        }
    
        fac[0]=1;
        for(int i=1;i<=n;++i){
            fac[i]=fac[i-1]%mod*i%mod;
        }
    
        cout<<C(x-1,L)%mod*fac[L]%mod*C(n-x,R)%mod*fac[R]%mod*fac[n-L-R-1]%mod<<endl;
    
        return 0;
    }
    
    

Codeforces Round #678 (Div. 2) C. Binary Search (二分,组合数)

标签:二分查找   alt   mic   题解   span   arc   构造   oid   技术   

原文地址:https://www.cnblogs.com/lr599909928/p/13881401.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!