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.
|
|
|
|
#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;
|
|
|
|
|
}
|
|
|
|
|
}
|