1076: 杨辉大三角 [逆元]
时间限制: 1 Sec 内存限制: 128 MB提交: 22 解决: 7 统计
题目描述
杨辉三角是个经典的数据模型,它形如:
KACA现在不满足求这些很小的数,他想要知道当nn和mm都比较大的时候的杨辉三角第nn行第mm列的值是多少。
输入
第一行有一个数字T(T≤2000)T(T≤2000)代表有TT组数据。
下面有T行,每一行有两个数字n(1≤n≤106),m(0≤m≤n)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; }