Live2D

bzoj2982: combination(lucas)

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));
	}
}

  

 

posted @ 2018-06-09 11:23  ztz11  阅读(185)  评论(0编辑  收藏  举报