C_Binary Search
C. Binary Search
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Andrey thinks he is truly a successful developer, but in reality he didn’t know about the binary search algorithm until recently. After reading some literature Andrey understood that this algorithm allows to quickly find a certain number 𝑥 in an array. For an array 𝑎 indexed from zero, and an integer 𝑥 the pseudocode of the algorithm is as follows:
Note that the elements of the array are indexed from zero, and the division is done in integers (rounding down).Andrey read that the algorithm only works if the array is sorted.
However, he found this statement untrue, because there certainly exist
unsorted arrays for which the algorithm find 𝑥!Andrey wants to write a letter to the book authors, but before doing
that he must consider the permutations of size 𝑛 such that the
algorithm finds 𝑥 in them. A permutation of size 𝑛 is an array
consisting of 𝑛 distinct integers between 1 and 𝑛 in arbitrary
order.Help Andrey and find the number of permutations of size 𝑛 which
contain 𝑥 at position 𝑝𝑜𝑠 and for which the given implementation
of the binary search algorithm finds 𝑥 (returns true). As the result
may be extremely large, print the remainder of its division by 109+7.Input The only line of input contains integers 𝑛, 𝑥 and 𝑝𝑜𝑠
(1≤𝑥≤𝑛≤1000, 0≤𝑝𝑜𝑠≤𝑛−1) — the required length of the
permutation, the number to search, and the required position of that
number, respectively.Output Print a single number — the remainder of the division of the
number of valid permutations by 109+7.Examples inputCopy 4 1 2 outputCopy 6 inputCopy 123 42 24 outputCopy
824071958 Note All possible permutations in the first test case:
(2,3,1,4), (2,4,1,3), (3,2,1,4), (3,4,1,2), (4,2,1,3), (4,3,1,2).
大概题意:
输入n,x,pos.(n表示全排列长度,x在数组pos位置上(从0开始))问多少个排列满足经过以下代码能输出为真:
思路分析:
二分;因为题目已经告诉a[mid]=x
,也就是已经知道了left的值,根据left逆推出对于不同区间的a[middle]与x的关系。只有a[middle] <= x
或者a[middle] > x
这两种情况。使用组合数计算出答案。
注意题面的二分做法与实际的二分板子不同。
根据上面的代码模拟就好,mid<=pos,则l=mid+1,if(mid<pos) v[mid]=-1(即应该小于x)。否则v[mid]=1.
然后就是一个组合数,统计v为1的数为z,-1为f。c=n-z-f-1;
代码在此:
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <iomanip>
#include <cmath>
#include <map>
#include <stack>
#include <algorithm>
#include <queue>
#include <set>
#include <cstdio>
typedef long long ll;
const int N = 1e3 + 7;
using namespace std;
const ll mod = 1e9 + 7;
int n, x, pos;
int a[N];
ll f[N];
ll qpow(ll xx,ll yy)
{
ll res = 1;
while(yy)
{
if(yy & 1) res = (res * xx) % mod;
xx = (xx * xx) % mod;
yy >>= 1;
}
return res % mod;
}
ll solve (int n,int m)
{
return f[n] * qpow(f[n - m] % mod, mod - 2) % mod;
}
int main()
{
f[0] = 1;
for(int i=1;i<=1000;i++) f[i] = i * f[i - 1] % mod;
scanf("%d%d%d",&n,&x,&pos);
for(int i=0;i<n;i++)
a[i] = i + 1;
int smaller = 0;
int bigger = 0;
int l = 0;
int r = n;
while(l < r)
{
int mid = (l + r) / 2;
if(a[mid] <= pos + 1)
{
l = mid + 1;
smaller++;
}
else
{
r = mid;
bigger++;
}
}
int els = n - smaller - bigger;
int B = n - x;
int S = x;
ll ans = solve(B, bigger) * solve(S - 1, smaller - 1) % mod * f[els] % mod;
printf("%lld\n",ans);
return 0;
}