(lucas) Saving Beans
題目:
Although winter is far away, squirrels have to work day and night to save beans. They need plenty of food to get through those long cold days. After some time the squirrel family thinks that they have to solve a problem. They suppose that they will save beans in n different trees. However, since the food is not sufficient nowadays, they will get no more than m beans. They want to know that how many ways there are to save no more than m beans (they are the same) in n trees.
Now they turn to you for help, you should give them the answer. The result may be extremely huge; you should output the result modulo p, because squirrels can’t recognize large numbers.
Input
The first line contains one integer T, means the number of cases.
Then followed T lines, each line contains three integers n, m, p, means that squirrels will save no more than m same beans in n different trees, 1 <= n, m <= 1000000000, 1 < p < 100000 and p is guaranteed to be a prime.
Output
You should output the answer modulo p.
Sample Input
2
1 2 5
2 1 5
Sample Output
3
3
Hint
For sample 1, squirrels will put no more than 2 beans in one tree. Since trees are different, we can label them as 1, 2 … and so on.
The 3 ways are: put no beans, put 1 bean in tree 1 and put 2 beans in tree 1. For sample 2, the 3 ways are:
put no beans, put 1 bean in tree 1 and put 1 bean in tree 2.
分析與解答
1.先說一下lucas
參考:https://blog.csdn.net/wyg1997/article/details/52152282
https://blog.csdn.net/wyg1997/article/details/52152282
lucas定理:
(圖片來自https://blog.csdn.net/arrowlll/article/details/53064748)
其實我們想一下二進制,111:就是1* 2^0+1*2^1+1*2^2
這個定理也是一樣的akak-1…..a1a0就是p進制的每一位
所以有如下解釋:
A、B是非負整數,p是質數。AB寫成p進制:A=a[n]a[n-1]…a[0],B=b[n]b[n-1]…b[0] 這里的每一個數組元素表示其p進制的每一位。
則組合數C(A,B)=C(a[n],b[n])C(a[n-1],b[n-1])…*C(a[0],b[0])。也就是說,把大組合數問題變成了一個個的小組合數。(A,B小于mod)
其實可以想一下快速冪,里面%2就是取二進制的最后一位數,/2就是二進制向前移動一位,所以怎么實現代碼也和快速冪類似,如下:
表達式:C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p。(可以遞歸)
這里如果n/p和m/p很大,我們仍然可去調用lucas
遞歸方程:(C(n%p, m%p)*Lucas(n/p, m/p))%p。(遞歸出口為m==0,return 1)
對于每一個c(n,k)我們要寫一個函數也就是求(n! / ( k! * ( n - k)! ) )%mod,由于有除法取模,所以我們要求k!*(n - k)!的逆元。
這里用小費馬求逆元,我們還需寫一個快速冪。由于組合數里面有階乘,所以我們還需打一個階乘表
整體下來就是這個樣子
這里對mod取模
2.再說一下這個題
m個小球放到n個盒子,盒子可以為空, 方案數就是:C(n+m-1,n-1)
這個題是m個果子放到n個樹上,類比一下,數就是盒子,小球就是果子,那么方案數就是C(n+m-1,n-1)
現在這個果子可以是0到m個,
所以總方案數
=C(n+m-1,n-1)+C(n+m-2,n-1)+…+C(n+1,n-1)+C(n,n-1)+C(n-1,n-1)
有一個組合數公式c(m,n)=c(m-1,n-1)+c(m-1,n)
這個組合數公式也可以看作:C(m,n-1)+C(m,n)=C(m+1,n)
還有個組合數公式:C(n,n)=1
所以我們從總方案數的后面變形
C(n-1,n-1)=C(n,n)
C(n-1,n-1)+C(n-1,n-1)=C(n,n)+C(n,n-1)=C(n+1,n)
現在后三個
C(n+1,n-1)+C(n,n-1)+C(n-1,n-1)=C(n+1,n-1)+C(n+1,n)=C(n+2,n)
我們發現,C(n+1,n-1)+C(n,n-1)+C(n-1,n-1)
這里m從2到0,上式等于C(n+2,n)
那么我們推廣到整個式子
C(n+m-1,n-1)+C(n+m-2,n-1)+…+C(n+1,n-1)+C(n,n-1)+C(n-1,n-1)
這里m從m到0,式子等于C(n+m,n)
推到這我們現在就只需求
C(n+m,m) % p
(我覺得我應該去學數學。。我愛數學啊)
現在這個題p不是固定的每次都會變,所以我們不能用打表了
C(n,m)=n!/(m!(n-m)!)
=(n*(n-1) … (n-m+1))/m!
分子從n-0一直到n-(m-1)也就是說循環m-1-0+1次也就是m次,而分母m!從1乘到m也是m次,那么我們就可以每次通過一個循環計算出C(n,m)了
參考:
https://blog.csdn.net/qq_27717967/article/details/51493877
這個是wrong answer 我也不知道為什么
后來改成預處理,lucas也改變,才對。
但是這個代碼改到上一個代碼的那個題上,就runtime error
我也不知道為什么,玄學就玄學到這了
輸入數據第一行是一個正整數T,表示數據組數 (T <= 100) 接下來是T組數據,每組數據有3個正整數 n, m, p (1 <= m <= n <= 10^9, m <= 10^4, m < p < 10^9, p是素數)第一個代碼對
1 <= n, m <= 1000000000, 1 < p < 100000 and p is guaranteed to be a prime.第二個代碼對
總結
以上是生活随笔為你收集整理的(lucas) Saving Beans的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 惠普z6计算机进不去桌面,HP Z6 桌
- 下一篇: 多线程销售问题java_Java多线程R