标签:二分查找 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