time limit: 10 sec
memory limit: 259 mb
submit: 2686
solved: 811 [
submit][
status][
discuss]
稱乙個1,2,…,n的排列p1,p2…,pn是magic的,當且僅當2<=i<=n時,pi>pi/2. 計算1,2,…n的排列中有多少是magic的,答案可能很大,只能輸出模p以後的值
輸入檔案的第一行包含兩個整數 n和p,含義如上所述。
輸出檔案中僅包含乙個整數,表示計算1,2,⋯, n的排列中, magic排列的個數模 p的值。
20 23
16 100%的資料中,1 ≤ n ≤ 106, p≤ 10^9,p是乙個質數。 資料有所加強
[ submit][
status][
discuss]
一開始,我很腦抽地領會錯了題目的意思。
我以為那個p(i)>p(i/2)只對偶數管用,根本沒想到i/2可以下去整
於是很快樂地做了乙個小時
又是楊輝三角,又是log表,又是素數
搞得不亦樂乎
結果,當樣例沒過是,我才意識到……
what the f***?
於是,重頭再來(有沒有搞錯,我的時間很寶貴誒)
算了,誰叫我不細心呢
於是我開始重新審視這道題
很容易聯想到二叉樹
因為對於乙個節點i,它下面對應著兩個節點i<<2和i<<2|1
所以,我們很自然地想到數字dp
所以我們設定兩個陣列size和f
f[i]表示以i為根節點的子樹的種類數
顯然最終答案是f[1]
size[i]是指以i為根節點的子樹的節點數
那麼轉移方程就出來了:
f[i]=f[i<<1]*f[i<<1|1]*c(size[i]-1,size[i-1]);這裡的c(n,m)表示組合數
那麼,接下來的重點,就是這個組合數
給的資料並不小誒
所以,我們就搬出了lucas定理
具體知識點回頭再說
**如下:
#include
#include
#include
using namespace std;
long long n,p;
long long f[2000005],size[2000005];
long long fac[2000005],inv[2000005];
void init()
for(int i=2;i<=n;i++)
for(int i=2;i<=n;i++)
}long long c(long long a,long long b)
if(areturn fac[a]*inv[b]%p
*inv[a-b]%p;
}return c(a%p,b%p)*c(a/p,b/p)%p;
}int main()
printf("%lld",f[1]);
return
0;}
Perm排列計數
記憶體限制 512 mib 時間限制 1000 ms 標準輸入輸出 題目描述 稱乙個1,2,n的排列p1,p2.pn是magic的,當且僅當2 i n時,pi pi 2.計算1,2,n的排列中有多少是magic的,答案可能很大,只能輸出模p以後的值 輸入格式 輸入檔案的第一行包含兩個整數 n和p,含...
Perm 排列計數
題目描述 稱乙個1,2,n的排列p1,p2.pn是magic的,當且僅當2 i n時,pi pi 2.計算1,2,n的排列中有多少是magic的,答案可能很大,只能輸出模p以後的值 輸入格式 輸入檔案的第一行包含兩個整數 n和p,含義如上所述。輸出格式 輸出檔案中僅包含乙個整數,表示計算1,2的排列...
Perm 排列計數
題目描述 稱乙個1,2,n的排列p1,p2.pn是magic的,當且僅當2 i n時,pi pi 2.計算1,2,n的排列中有多少是magic的,答案可能很大,只能輸出模p以後的值 輸入格式 輸入檔案的第一行包含兩個整數 n和p,含義如上所述。輸出格式 輸出檔案中僅包含乙個整數,表示計算1,2,的排...