二维前缀和: 小口诀:上加左 减左上 加自己
a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1]
然后是杨辉三角 即C(i,j)=C(i-1,j)+C(i-1,j-1)
for(int i=0;i<=n;i++) { c[i][0]=1; for(int j=0;j<=i;j++) c[i][j]=c[i-1][j]+c[i-1][j-1]; }
还有一种来自刘汝佳大佬小粉书上的求法 求C(n,k) C(n,k)=(n-k+1)/k*C(n,k-1) 然后就可以从C(n,0)=1开始递推
1 #include<bits/stdc++.h> 2 using namespace std; 3 int t,k; 4 int a[2001][2001]; 5 int ans[2001][2001]; 6 int n[10001],m[10001]; 7 int main() 8 { 9 int x=0; 10 scanf("%d%d",&t,&k); 11 for (int i=1;i<=t;i++) 12 { 13 scanf("%d%d",&n[i],&m[i]); 14 if (n[i]>x) x=n[i]; 15 } 16 for (int i=1;i<=x;i++) 17 { 18 a[1][i]=i%k; 19 if (a[1][i]==0) ans[1][i]++; 20 } 21 for (int i=2;i<=x;i++) 22 for (int j=2;j<=i;j++) 23 { 24 a[j][i]=(a[j-1][i-1]+a[j][i-1])%k; 25 if (a[j][i]==0) ans[j][i]++; 26 } 27 for (int i=1;i<=x;i++) 28 for (int j=1;j<=x;j++) 29 ans[j][i]+=ans[j-1][i]+ans[j][i-1]-ans[j-1][i-1]; 30 for (int i=1;i<=t;i++) printf("%d\n",ans[min(n[i],m[i])][n[i]]);