# 组合数问题

## 题目描述

$\binom{n}{m}=\frac{n!}{m!(n-m)!}$

## 输入输出格式

### 输出格式

$t$ 行，每行一个整数代表所有的 $0\leq i\leq n,0\leq j\leq \min \left ( i, m \right )$ 中有多少对 $(i,j)$ 满足 $k|\binom{i}{j}$

1 2
3 3

1

2 5
4 5
6 7

0
7

## 说明

【样例1说明】

【子任务】

• 对于全部的测试点，保证 $0 \leq n, m \leq 2 \times 10^3$$1 \leq t \leq 10^4$

# 分析

void init(int k) {
c[0][0] = c[1][0] = c[1][1] = 1;
for (int i = 2; i < maxn; ++i) {
c[i][0] = 1;
for (int j = 1; j <= i; ++j) {
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % k;
}
}
}

$ans_{i, j} = ans_{i - 1, j} + ans_{i, j - 1} - ans_{i - 1, j - 1}$

void init(int k) {
c[0][0] = c[1][0] = c[1][1] = 1;
for (int i = 2; i < maxn; ++i) {
c[i][0] = 1;
for (int j = 1; j <= i; ++j) {
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % k;
ans[i][j] = ans[i - 1][j] + ans[i][j - 1] - ans[i - 1][j - 1];
if (c[i][j] == 0) ++ans[i][j];
}
}
}

void init(int k) {
c[0][0] = c[1][0] = c[1][1] = 1;
for (int i = 2; i < maxn; ++i) {
c[i][0] = 1;
for (int j = 1; j <= i; ++j) {
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % k;
ans[i][j] = ans[i - 1][j] + ans[i][j - 1] - ans[i - 1][j - 1];
if (c[i][j] == 0) ++ans[i][j];
}
ans[i][i + 1] = ans[i][i];
}
}

# 代码

/*
* @Author: crab-in-the-northeast
* @Date: 2020-10-01 14:01:33
*/
#include <iostream>
#include <cstdio>

const int maxn = 2005;
const int maxm = 2005;
long long c[maxn][maxm], ans[maxn][maxm];

void init(int k) {
c[0][0] = c[1][0] = c[1][1] = 1;
for (int i = 2; i < maxn; ++i) {
c[i][0] = 1;
for (int j = 1; j <= i; ++j) {
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % k;
ans[i][j] = ans[i - 1][j] + ans[i][j - 1] - ans[i - 1][j - 1];
if (c[i][j] == 0) ++ans[i][j];
}
ans[i][i + 1] = ans[i][i];
}
}

int main() {
int t, k;
std :: scanf("%d %d", &t, &k);
init(k);
while (t--) {
int n, m;
std :: scanf("%d %d", &n, &m);
std :: printf("%lld\n", ans[n][m > n ? n : m]);
}
return 0;
}

# 评测记录

posted @ 2020-10-01 16:20  东北小蟹蟹  阅读(156)  评论(0编辑  收藏