题目链接:点击进入
题目
题意
给你一个二分查找算法,给你目标值 x 以及在数组中的位置 pos,数组是长度为 n 的排列,问有多少种排列方式,可以通过这个二分查找算法找到 x
思路
根据这个二分查找算法,在 0 - n - 1 的下标中找 pos,假设经过pos左边(小)sl 次,经过右边(大)sr 次,比 x 小的值有 x - 1 ( sn )个,比 x 大的值有 n - x ( sx )个,在小的中选 sl 个全排列,在大的中选 sr 个全排列,剩下的全排列,最终结果就是
A ( sn , sl ) * A ( sx , sr ) * A ( sn - sl + sx - sr , sn - sl + sx - sr )
代码
//#pragma GCC optimize(3)//O3
//#pragma GCC optimize(2)//O2
#include<iostream>
#include<string>
#include<map>
#include<set>
//#include<unordered_map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define best 131
#define INF 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
#define lowbit(x) x & -x
#define inf 0x3f3f3f3f
#define int long long
//#define double long double
//#define max(a,b) a>b?a:b
//#define min(a,b) a<b?a:b
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai=acos(-1.0);
const int maxn=1e6+10;
const int mod=1e9+7;
const double eps=1e-9;
const int N=1e6+10;
int t,n,m,a[maxn],x,pos;
ll A(ll n,ll m)
{
ll ans=1;
for(ll i=n;i>=n-m+1;i--)
ans=(ans*i)%mod;
return ans;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>x>>pos;
int sx=n-x,sn=x-1,sl=0,sr=0;
int l=0,r=n;
while(l<r)
{
int mid=l+r>>1;
if(mid<=pos)
{
l=mid+1;
if(mid<pos) sl++;
}
else
r=mid,sr++;
}
int ans=A(sn,sl)*A(sx,sr)%mod*A(sn-sl+sx-sr,sn-sl+sx-sr)%mod;
cout<<ans<<endl;
return 0;
}