1. 程式人生 > >bzoj2982: combination(lucas)

bzoj2982: combination(lucas)

return std ostream In lld scrip strong 選擇 n)

Description

LMZn個不同的基友,他每天晚上要選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)