luogu p2282 組合數問題

2021-10-19 04:20:03 字數 2728 閱讀 7904

傳送門

組合數 \(\binom\) 表示的是從 \(n\) 個物品中選出 \(m\) 個物品的方案數。舉個例子,從 \((1,2,3)\) 三個物品中選擇兩個物品可以有 \((1,2),(1,3),(2,3)\) 這三種選擇方法。根據組合數的定義,我們可以給出計算組合數 \(\binom\) 的一般公式:

\[\binom=\frac \]

其中 \(n!=1\times2\times\cdots\times n\);特別地,定義 \(0!=1\)。

小蔥想知道如果給定 \(n,m\) 和 \(k\),對於所有的 \(0\leq i\leq n,0\leq j\leq \min \left ( i, m \right )\) 有多少對 \((i,j)\) 滿足 \(k|\binom\)。

第一行有兩個整數 \(t,k\),其中 \(t\) 代表該測試點總共有多少組測試資料,\(k\) 的意義見問題描述。

接下來 \(t\) 行每行兩個整數 \(n,m\),其中 \(n,m\) 的意義見問題描述。

共 \(t\) 行,每行乙個整數代表所有的 \(0\leq i\leq n,0\leq j\leq \min \left ( i, m \right )\) 中有多少對 \((i,j)\) 滿足 \(k|\binom\)。

1 2

3 3

1
2 5

4 56 7

0

7

【樣例1說明】

在所有可能的情況中,只有 \(\binom = 2\) 一種情況是 \(2\) 的倍數。

【子任務】

這題一看就要用 \(\operatorname(n ^ 2)\) 預處理 \(\operatorname(1)\) 回答的演算法,那麼具體怎麼做呢?

首先用楊輝三角預處理出2000內所有的組合數對 \(k\) 取模的結果。如下:

void init(int k) }}

然後仔細觀察題目要求什麼:

對於所有的 \(0\leq i\leq n,0\leq j\leq \min \left ( i, m \right )\) 有多少對 \((i,j)\) 滿足 \(k|\binom\)。

為了方便討論,若 \(m > n\),我們一律令 \(n \rightarrow m\)。

定義 \(ans_\) 為答案陣列,用二維字首和得到公式:

\[ans_ = ans_ + ans_ - ans_ \]

當然,如果我們發現 \(k|\binom\),那麼 \(ans_\) 還需自增 \(1\)。

我們就可以寫出這樣的**:

void init(int k) }}

然而就這樣結束了嗎?

如果這樣,提交程式,你會發現你的**能拿到15分的好成績。

這是為什麼呢?

不妨來看看當 \(k = 5\) 時,ans的表如何。(此處列舉了前10*10個)

顯然,綠色方塊的值是紅+藍-紫。但是你發現沒有,紅色方塊的所在位置已經超出了楊輝三角的預處理範圍。(橙色左下方為預處理範圍,右上角為非預處理範圍),也就是當 \(i = j\) 時,\(ans_\) 沒有被處理。

但是,這個東西其實很好處理,因為 \(ans_ = ans_\)。至於這是為什麼,見其定義:

對於所有的 \(0\leq i\leq n,0\leq j\leq \min \left ( i, m \right )\) 有多少對 \((i,j)\) 滿足 \(k|\binom\)。

觀察到這個 \(min(i, m)\) 了嗎?這個的意思就是說,當 \(m > n\) 時,\(ans_\) 和 \(ans _\) 其實是等價的。

同樣的道理便可以得到 \(ans_ = ans_\)。因此只要在i迴圈中最後加一句ans[i][i + 1] = ans[i][i];即可。**如下:

void init(int k) 

ans[i][i + 1] = ans[i][i];}}

這樣就可以ac啦~上乙個整體**吧!

/*

* @author: crab-in-the-northeast

* @date: 2020-10-01 14:01:33

* @last modified by: crab-in-the-northeast

* @last modified time: 2020-10-01 16:18:48

*/#include #include const int maxn = 2005;

const int maxm = 2005;

long long c[maxn][maxm], ans[maxn][maxm];

void init(int k)

ans[i][i + 1] = ans[i][i];

}}int main()

return 0;

}

評測記錄

LUOGU P2822 組合數問題

題面 由於要求對k取模為0的值,所以我們遞推求組合數時一直對k取模就行了 然後算出二維字首和,o n 2 預處理,o 1 回答。bzoj上和這個不太一樣,那個是要盧卡斯定理。include define ll long long using namespace std const int maxn ...

luogu P2822 組合數問題

題面傳送門 對於這道題,其實題目很簡單,暴力很好打。想法1 11 對於每組輸入資料,暴力判斷兩重迴圈列舉,一重迴圈計算組合數。時間複雜度o t n3 o tn 3 o tn3 大概30 3030 分想法2 22 把每組數的組合存下來,直接呼叫。時間複雜度o t n2 o tn 2 o tn2 大概3...

NOIP2016 洛谷2282 組合數問題

題目描述 組合數表示的是從n個物品中選出m個物品的方案數。舉個例子,從 1,2,3 三個物品中選擇兩個物品可以有 1,2 1,3 2,3 這三種選擇方法。根據組合數的定 義,我們可以給出計算組合數的一般公式 其中n 1 2 n 小蔥想知道如果給定n,m和k,對於所有的0 i n,0 j min i,...