组合数打表+二维前缀数组优化——组合数问题

来源:互联网 发布:log4j2 java web 编辑:程序博客网 时间:2024/05/30 02:22

题目来源

洛谷P2822组合数问题

https://www.luogu.org/problem/show?pid=2822


思路

输入t和k之后 预处理一个模k意义下的2000的杨辉三角表

前缀数组num[n][m]记录C(0,0)~C(n,m)的矩形中有意义且(%k后)为0的组合数的数量

可以证得num[i][j]即为题中所求的对于所有的0<=i<=n,0<=j<=min(i,m)中满足C(i,j)是k的倍数的(i,j)的数量。



C_n^m

代码(C++)


C_n^m
~

C_n^

#include <cstdio>using namespace std;int T,k,n,m,s,yh[2010][2010];long long num[2010][2010];inline void preyhsj();//预处理 int main(){scanf("%d%d",&T,&k);preyhsj();for(int t=1;t<=T;++t){scanf("%d%d",&n,&m);printf("%lld\n",num[n][m]);}return 0;}inline void preyhsj(){yh[0][0]=1;for(int i=1;i<=2000;++i){yh[i][0]=1;yh[i][i]=1;s=0;for(int j=1;j<=i;++j){yh[i][j]=(yh[i-1][j-1]+yh[i-1][j])%k;if(yh[i][j]==0)++s;num[i][j]=num[i-1][j]+s;}for(int j=i+1;j<=2000;++j)num[i][j]=num[i][j-1];}return ;}