bzoj2982: combination(lucas)
阿新 • • 發佈:2018-06-09
return std ostream In lld scrip strong 選擇 n)
Description
LMZ有n個不同的基友,他每天晚上要選m個進行[河蟹],而且要求每天晚上的選擇都不一樣。那麽LMZ能夠持續多少個這樣的夜晚呢?當然,LMZ的一年有10007天,所以他想知道答案mod 10007的值。(1<=m<=n<=200,000,000)Input
第一行一個整數t,表示有t組數據。(t<=200) 接下來t行每行兩個整數n, m,如題意。Output
T行,每行一個數,為C(n, m) mod 10007的答案。思路:
不想說什麽,標準的lucas,比luogu上的板子還簡單
lucas大家應該都知道,不知道的可以看我的博客(抱歉啊,還有bug,沒發布)
核心代碼就一行:
(lucas(s/p,t/p)*zhs(s%p,t%p))%p
重點在預處理逆元
代碼:
#include<iostream> #include<cstdio> using namespace std; long long n,m,p,t,ny[100005]; void qny() { ny[1]=1; for(register int a=2;a<=p-1;a++) { ny[a]=(p-(p/a))*ny[p%a]%p; } } int zhs(int q,int x) { if(q==0) { return 1; } long long ltt=1; for(register int a=1;a<=q;a++) { ltt*=ny[a]; ltt%=p; } for(register int a=1;a<=q;a++) { ltt*=(x-a+1); ltt%=p; } return ltt; } long long lucas(int s,int t) { if(t==0) { return 1; } else { return (lucas(s/p,t/p)*zhs(s%p,t%p))%p; } } int main() { scanf("%d",&t); p=10007; qny(); for(int i=1;i<=t;i++) { scanf("%d%d",&n,&m); printf("%lld\n",lucas(m,n)); } }
bzoj2982: combination(lucas)