• 【CF1436C】Binary Search 题解


    原题链接

    题意简介

    要求有多少种 n 的排列,能够通过二分法正确地找到放在 pos 处的数字 x。
    答案对 1e9+7 取模。n<=1000。

    采用的二分法如下图:

    思路分析

    首先,这个排列中有一个位置是固定的,就是 a[pos] = x 。

    我们知道,二分查找的过程是不断缩小区间的过程,想要找到一个已经确定放在 pos 位置上的 x ,需要判断的 mid 的位置,需要的大于 x 的数的个数 c1 和小于 x 的数的个数 c0 也是固定的。

    也就是说,我们只需要模拟这个二分过程,求解出 c0 和 c1,然后利用排列组合的公式去计算就行了。

    (Ans = A^{c0}_{x-1} imes A^{c1}_{n-x} imes (n-1-c0-c1)!)

    由于本题的 n 的范围较小,可以不写逆元,直接暴力求阶乘。

    顺带一提,本题有一个坑点在于不一定有解。显然的,当小于 x 的数不够 c0 个或大于 x 的数不够 c1 个时无解。

    代码库

    #include <cstdio>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define Rep(i,a,b) for(int i=a;i>=b;i--)
    typedef long long ll;
    const int MOD=1e9+7,N=1002;
    inline ll _pow(ll x,ll p){
        ll ans=1;
        while(p){
            if(p&1) ans=ans*x%MOD;
            p>>=1; x=x*x%MOD;
        }
        return ans;
    }
    int n,x,pos,c0,c1;
    ll fact[N];
    int main(){
        scanf("%d%d%d",&n,&x,&pos);
        int l=0,r=n,mid;
        while(l<r){
            mid=(l+r)>>1;
            if(mid<pos) c0++,l=mid+1;
            else if(mid==pos) l=mid+1;
            else c1++,r=mid;
        }
        fact[0]=1;
        rep(i,1,n) fact[i]=(fact[i-1]*i)%MOD;
        if(x-1-c0<0||n-x-c1<0||n-1-c0-c1<0) printf("0
    ");
        else printf("%lld
    ",fact[x-1]*_pow(fact[x-1-c0],MOD-2)%MOD*fact[n-x]%MOD*_pow(fact[n-x-c1],MOD-2)%MOD*fact[n-1-c0-c1]%MOD);
        return 0;
    }
    

    END

  • 相关阅读:
    ViScript 1.0 Released
    How to: 修改程序的拖拽行为
    API Hooking 的原理
    小T历险记
    我的酒窝.NET
    MSN Space
    Naive Container 发布1.0版本
    EFT acceptance and functional testing tool for Windows application
    [译]JavaScript:如何判断值的类型
    [译]JavaScript:多行字符串
  • 原文地址:https://www.cnblogs.com/Qing-LKY/p/CF1436C-solution.html
Copyright © 2020-2023  润新知