洛谷 P2822 組合數問題

2022-05-31 14:57:08 字數 1789 閱讀 9482

已知組合數(從\(n\)個物品中選擇\(m\)個物品的方案數)

\[c^m_n=c(n,m)=\binom=\frac

\]其中

\[n! = 1 \times 2 \times 3 \times \cdots \times n

\]\(specially\),\(define 0!=1\)

給定\(n\),\(m\),\(k\),對於所有的\(0 \le i \le n\),\(0 \le j \le min(i,m)\),有多少對\((i,j)\)滿足\(k \mid \)

求\[\sum_^n \sum_^ [k \mid c_i^j]

\]這個求和的方式就非常清晰了。那麼我們現在只用關係一下幾個問題:

看到\(n\),\(m\)最大只有\(2\times10^3\),但是\(t \le 10^4\),不難想到打表。

那麼怎麼遞推地求\(c_i^j\)呢?組合數有乙個重要的性質:

\[c_n^m=c_^m+c_^

\]可以從兩個方面給出解釋:

感性理解

從\(n\)個物品中拿出\(m\)個物品的方案數,相當於從\(n-1\)個物品中拿出\(m-1\)個物品(第\(n\)個物品不拿)的方案數+從\(n-1\)個物品中拿出\(m\)個物品(拿上第\(n\)個)的方案數

理性推導

\[\begin

c_^+c_^&=\frac + \frac\\

&=(n-1)! \times \frac\\

&=\frac\\

&=c^m_n

\end

\]時間上可以過去了,但是組合數會爆\(\texttt\)啊!

這個也很簡單解決

因為k是不變的,利用取模運算的加法原理,即\((a \% p+b\%p)\%p=(a+b)\%\),我們可以知道,我們想要知道的僅僅是這個數模\(k\)剩多少,用餘數遞推也是可以的。

最後用二位字首和儲存乙個區間內可以將\(k\)整除的組合數的個數即可。

#include#include#include#include#include#include#include#include#include#define il inline

#define re register

#define ll long long

#define ull unsigned long long

#define re register

#define debug printf("now is %d\n",__line__);

using namespace std;

templateinline void read(t&x)

}inline int read()

return x;

}int g[55];

templateinline void write(t x)

while(x);

for(re int i=g;i>=1;--i)putchar('0'+g[i]);putchar('\n');

}int t,k;

ll c[2010][2010],s[2010][2010];

void pre()

for(int i=1;i<=2000;i++)

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

int main()

{ t=read();

k=read();

pre();

while(t--)

{ int i=read();

int j=read();

cout《注意組合數上下兩個字母的含義,不要寫反了。

洛谷P2822 組合數問題

題目描述 組合數 cmn m在上,n在下 表示的是從 n個物品中選出 m 個物品的方案數。舉個例子,從 1,2,3 三個物品中選擇兩個物品可以有 1,2 1,3 2,3 這三種選擇方法。根據組合數的定義,我們可以給出計算組合數 cmn的一般公式 其中 n 1 2 n 特別地,定義 0 1。小蔥想知道...

洛谷P2822 組合數問題(題解)

題目傳送 先了解一下有關組合數的公式 m在上,n在下 發現組合數的遞推的直觀影象形式就是楊輝三角 第i行第j列的數等於c i 1,j 1 由於題目要求多組組合數,便可以遞推組合數做預處理 直接用通項公式算什麼的太粗暴 慢 了 一看資料範圍,保證讓普通範圍溢位的節奏啊,但定心一看,我們只用知道每個組合...

P2822 組合數問題

題目描述 組合數c n mc n m 表示的是從n個物品中選出m個物品的方案數。舉個例子,從 1,2,3 三個物品中選擇兩個物品可以有 1,2 1,3 2,3 這三種選擇方法。根據組合數的定 義,我們可以給出計算組合數的一般公式 c n m m n m n 其中n 1 2 n 不清楚不要怪我,暫時找...