题目
题
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ba70d400e9721787a0989a0cfcdda141.png)
输入 输出
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e6364333483d8101c696ed5f4cd67ce0.png)
思路
一个范围
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e40a296974a3609b74fe511ecc58404f.png)
求二维 的前缀和
二维前缀和公式
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9971de4f2ae93c05d8ee76f71c934802.png)
如何快速求一个组合数是否能整除k?
组合数的递推式
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/7dd888c39d91b70ae7366887885a5cc4.png)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int N = 2010;
int c[N][N];
int s[N][N];
int main()
{
int T,k;
cin >> T >> k;
for(int i = 0; i < N;i++)
for(int j = 0;j <= i;j++)
{
if(!j) c[i][j] = 1 % k;
else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % k;
}
for(int i = 0;i < N;i++)
{
for(int j = 0;j < N;j++)
{
if(j <= i && c[i][j] == 0) s[i][j] = 1;
if(i - 1 >= 0) s[i][j] += s[i - 1][j];
if(j - 1 >= 0) s[i][j] += s[i][j - 1];
if(i - 1 >= 0 && j - 1 >= 0) s[i][j] -= s[i - 1][j - 1];
}
}
while(T--)
{
int n,m;
cin >> n >> m;
cout << s[n][m] << endl;
}
return 0;
}