題面傳送門
對於這道題,其實題目很簡單,暴力很好打。
想法1
11:對於每組輸入資料,暴力判斷兩重迴圈列舉,一重迴圈計算組合數。時間複雜度o(t
n3
)o(tn^3)
o(tn3)
,大概30
3030
分想法2
22:把每組數的組合存下來,直接呼叫。時間複雜度o(t
n2
)o(tn^2)
o(tn2)
大概35
3535
分。想法3
33:既然直接算組合數會爆精度,那麼在計算組合數是就不能有除法和減法,只有加法和乘法滿足(a%
c)(b
%c)%
c=(a
b)%c
(a\%c)(b\%c)\%c=(ab)\%c
(a%c)(
b%c)
%c=(
ab)%
c與(a%c
+b%c
)%c=
(a+b
)%
c(a\%c+b\%c)\%c=(a+b)\%c
(a%c+b
%c)%
c=(a
+b)%
c.然後我們自然想起楊輝三角,這是乙個求組合數的東西,遞推公式為fi,
j=fi
−1,j
+f+i
−1,j
−1
f_=f_+f+
fi,j=
fi−1
,j+
f+i−
1,j−
1,所以我們可以遞推出來,一遍遞推一遍%k,對於每組資料遞推一遍,若%k=
=0
\%k==0
%k==
0即有乙個答案。大概有70
7070
分。想法4
44:因為楊輝三角是一樣的,所以可以先遞推出來。
遞推出來有什麼用啊,還不是要o(n
2)
o(n^2)
o(n2
)查詢。
這可是提高組原題,提高組不考資料結構考什麼。
那麼有一種資料結構,修改很麻煩,但查詢o(1
)o(1)
o(1)
。所以我們可以用字首和過掉這一題。
關於二維字首和之前的題解已經有講過,不再贅述。
**實現:
#include
#define min(a,b) ((a)<(b)?(a):(b))
using
namespace std;
int n,m,x,y,f[
2039][
2039
],s[
2039][
2039
],ans,tot,pus;
intmain()
s[i]
[i+1
]=s[i]
[i];
}for
(i=1
;i<=n;i++
)return0;
}
順帶提一下,當y
>
xy>x
y>
x的時候解為sx,
xs_
sx,x
,因為在x
xx個數中選y
yy個數一定選不出來。
評測記錄
然而我們發現每次都要近似2000
×2000
2000\times2000
2000×2
000的迴圈太浪費時間,有些時候沒必要遞推這麼多,所以我們可以記錄最大的n
nn,並按此遞推(真心怕出題人毒瘤)
**實現:
#include
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
using
namespace std;
int n,m,x[
10039
],y[
10039
],f[
2039][
2039
],s[
2039][
2039
],ans,tot,pus;
intmain()
s[i]
[i+1
]=s[i]
[i];
}for
(i=1
;i<=n;i++
)printf
("%d\n"
,s[x[i]][
min(x[i]
,y[i])]
);return0;
}
評測記錄
資料小的點就跑得飛起。
附:字首和題解
LUOGU P2822 組合數問題
題面 由於要求對k取模為0的值,所以我們遞推求組合數時一直對k取模就行了 然後算出二維字首和,o n 2 預處理,o 1 回答。bzoj上和這個不太一樣,那個是要盧卡斯定理。include define ll long long using namespace std const int maxn ...
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 不清楚不要怪我,暫時找...
P2822 組合數問題
小蔥想知道如果給定 n,m 和 k,對於所有的 0 i n,0 j min i,m 有多少對 i,j i,j 滿足 ci取j 是 k 的倍數。輸入格式 第一行有兩個整數 t,kt,k,其中 tt 代表該測試點總共有多少組測試資料,k 的意義見問題描述。接下來 tt 行每行兩個整數 n,m,其中 n,...