51Nod1799 二分答案

2021-08-04 09:34:44 字數 1276 閱讀 6239

lyk最近在研究二分答案類的問題。

對於乙個有n個互不相同的數且從小到大的正整數數列a(其中最大值不超過n),若要找乙個在a中出現過的數字m,乙個正確的二分程式是這樣子的:

l=1; r=n; mid=(l+r)/2;

while (l<=r)

最終a[r]一定等於m。

但是這個和諧的程式被熊孩子打亂了。

熊孩子在一開始就將a陣列打亂順序。(共有n!種可能)

lyk想知道最終r=k的期望。

由於小數點非常麻煩,所以你只需輸出將答案乘以n!後對1000000007取模就可以了。

在樣例中,共有2個數,被熊孩子打亂後的數列共有兩種可能(1,2)或者(2,1),其中(1,2)經過上述操作後r=1,(2,1)經過上述操作後r=0。r=k的期望為0.5,0.5*2!=1,所以輸出1。

input

3個整數n,m,k(1<=m<=n<=10^9,0<=k<=n)。

output

一行表示答案

input示例

2 1 1

output示例

1題解

如果r=k,那麼每次二分找的數的位置都是固定的,所以我們只需確定這些位置的數與m的大小關係,我們就可以控制二分的位置,利用組合數學計算答案。另外,階乘太大需要打表。

**

#include

#include

#include

#include

#include

#define mod 1000000007

typedef long long ll;

using namespace std;

inline int

read()

while (ch>='0'&&ch<='9')

return

x*f;

}const int l=1e7;

const int c=

; int n,m,k,mid,big,small;

ll cal(intx)

int main()

ll ans=1;

for (int i=n-m-big+1;i<=n-m;i++)

ans=(ans*i)%mod;

for (int i=m-small+1;i<=m;i++)

ans=(ans*i)%mod;

printf("%lld",(ans*cal(n-big-small))%mod);

return

0;}

51nod1799 二分答案 分塊打表

分析 要走到乙個位置的話一共要往左或者往右走o logn 次,而且每一步都必須走對。因為對於題目中給出的 無論k是什麼樣的數,二分過程的次數都是固定的。每走一步只和ami d 的大小關係有關,因此有一些位置只能放 m 或者 m的數,其他 位置可以隨便放。階乘可 以分段打表。includeusing ...

51nod 1799 思維 二分 數論 分塊打表

題目鏈結 很好的題目,很早就關注了此題,但一直沒看懂題解,今天在紙上模擬了很久終於了有了新的感悟 對於這種 求期望 n m od1e 9 7求期望 n mod 1e9 7 求期望 n mod1 e9 7 的問法實際上就是求方案數。雖然數列完全打亂了,但其實對於二分結果的影響並沒有直觀上的那麼大。形如...

1799 二分答案

lyk最近在研究二分答案類的問題。對於乙個有n個互不相同的數且從小到大的正整數數列a 其中最大值不超過n 若要找乙個在a中出現過的數字m,乙個正確的二分程式是這樣子的 l 1 r n mid l r 2 while l r 最終a r 一定等於m。但是這個和諧的程式被熊孩子打亂了。熊孩子在一開始就將...