hpuoj 1076 杨辉大三角

1076: 杨辉大三角 [逆元]

时间限制: 1 Sec  内存限制: 128 MB

提交: 22  解决: 7  统计

题目描述

杨辉三角是个经典的数据模型,它形如:


KACA现在不满足求这些很小的数,他想要知道当nnmm都比较大的时候的杨辉三角第nn行第mm列的值是多少。

输入

第一行有一个数字T(T2000)T(T≤2000)代表有TT组数据。

下面有T行,每一行有两个数字n(1n106),m(0mn)n(1≤n≤106),m(0≤m≤n)

输出

对于每一组输入,你应该输出一个数字,代表第nn行第mm列杨辉三角的数字,因为数字可能很大,所以你只需要输出其对10000031000003取模后的结果。

样例输入

3
1 1
2 1
3 2

样例输出

1
1
2

这道题是要利用逆元和组合数学的知识来进行解决,如果单纯的使用二维数组肯定会不行,因为数据范围太大,肯定不能构建二维数组,因此我们就要利用组合数学的知识了。我们知道C(n+1,i+1)=C(n+1,i)+C (n,i),这刚好满足杨辉三角的构成原理,级第n行第m列的元素为C (n-1,m-1);(看的师傅的代码才知道有这种求法点击打开链接

利用逆元不难求出答案,下面放代码:

#include<stdio.h>
long long p=1000003;
typedef long long ll;
#define maxn 1000005
ll a[maxn];
ll exgcd(ll a,ll b,ll &x,ll &y)//扩展欧几里得 
{
	int t;
	if(!b)
	{
		x=1;
		y=0;
		return 0;
	}
	exgcd(b,a%b,x,y); 
	t=x;
	x=y;
	y=t-a/b*x;
}
ll inv(ll a)//求逆元 
{
	ll x,y;
	exgcd(a,p,x,y);
	return (x+p)%p;
}
void init()//阶乘函数 
{
    a[0]=1;
	for(int i=1;i<maxn;i++)
	{
		a[i]=(a[i-1]*i)%p;
	}	
}
int main()
{
	init();
	ll n,m;
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%lld %lld",&n,&m);
		printf("%d\n",(a[n-1]*inv(a[n-m])*inv(a[m-1]))%p);//答案 
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/duanghaha/article/details/79563106