洛谷 P2822 组合数问题(数学||组合数)

题目链接:https://www.luogu.com.cn/problem/P2822

运用杨辉三角递推预处理出组合数。用二维前缀和记录有多少对满足k|(i,j)。

在预处理组合数时,因为最终都要除以k,所以可以在递推求的时候%k。注意二维前缀和求的时候的边界情况:

sum[i][i+1]=sum[i][i]。

再注意输入中m可能大于n。

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 const int N=2005;
 5 int T,k;
 6 int c[N][N],sum[N][N];
 7 void init(){
 8     c[1][1]=1;
 9     for(int i=0;i<=2000;i++) c[i][0]=1;
10     for(int i=2;i<=2000;i++)
11     for(int j=1;j<=i;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%k;
12     for(int i=2;i<=2000;i++){
13         for(int j=1;j<=i;j++){
14             sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
15             if(c[i][j]==0) sum[i][j]++;
16         }
17         sum[i][i+1]=sum[i][i];
18     }
19 }
20 int main(){
21     scanf("%d%d",&T,&k);
22     init();
23     while(T--){
24         int n,m;
25         scanf("%d%d",&n,&m);
26         if(m>n) m=n;
27         printf("%d
",sum[n][m]);
28     }
29     return 0;
30 }
AC代码
原文地址:https://www.cnblogs.com/New-ljx/p/13910355.html