You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

42 lines
1.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2010; //n的数值上限
int t; //t次查询
int n; //n个数字中
int m; //找m个数字组合
int K; //给定k求k的倍数
int C[N][N]; //组合数数组
int s[N][N]; //二维前缀和
int main() {
//默认初始值-1,之所以初始为-1是怕默认的0无法描述是模完变成的0还是天生默认就是0-1就有这个好处。
memset(C, -1, sizeof C);
cin >> t >> k;
//预处理杨辉三角形
for (int i = 0; i < N; i++) {
//base case
C[i][0] = C[i][i] = 1; //组合数C(n,0)=1 组合数C(n,n)=c(n,0)=1
//递推生成其它组合数
//因为是求组合数C(A,B)那么A一定要大于等于B否则就不对了。
//所以j的循环范围最大就只能是i
for (int j = 1; j < i; j++)//因为一头一尾j-->0和i都被手动设置了1所以循环的范围就是中间剩下的了。
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % k;//因为C数组中已有的数据都是被%k后存入的
// 所以这里做加法前不用再%,再%也是那么回事,反而速度更慢了。
}
//标准的二维前缀和
for (int i = 1; i < N; i++)
for (int j = 1; j < N; j++)
s[i][j] = (C[i][j] == 0 ? 1 : 0) + s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1];
//处理t次询问
while (t--) {
cin >> n >> m;
cout << s[n][m] << endl;
}
}