火車進出棧問題 卡特蘭數

2022-05-19 06:24:13 字數 2200 閱讀 9692

《更新提示》

《第一次更新》

《正文》

一列火車n節車廂,依次編號為1,2,3,…,n。每節車廂有兩種運動方式,進棧與出棧,問n節車廂出棧的可能排列方式有多少種。

乙個數,n(n<=65000)

乙個數s表示n節車廂出棧的可能排列方式

3
5
轉換一下題意:求卡特蘭數的第\(n\)項,不取模。

先考慮\(n\)小一點的做法,我們可以直接用卡特蘭數的線性遞推公式:

\[f_n=f_\frac

\]然後直接敲高精度乘除就可以得到\(52\)分的高分啦。

然後考慮一下優化:我們發現數字位數超級多,可以寫乙個壓位高精,這樣又可以多得\(20-30\)分。

然後再想一想正解,我們要換乙個思路,應該用這個公式:

\[f_n=\frac^n}

\]這是卡特蘭數的通項公式,我們可以利用組合數的定義式簡單的推導一下。

\[⇒f_n=\frac

\\ \ \\⇒f_n=\frac\]

看一下算數基本定理:

\[a=p_1^*p_2^*...*p_k^

\]注意到卡特蘭數每一項都一定是乙個整數,也就是說,如果將如上公式的分子分母分別分解質因數,那麼分母的各個因式指數上一定是可以被分子的各個因式相減抵消的。

這樣,高精度除法就不用寫了,這是乙個巨大的突破。

但是分子分母都是存在階乘結構的,那麼就考慮然後對某個數的階乘分解質因數。

對於\(!n=1*2*...*n\),考慮他存在多少個質因子\(p\)。

**片段:將\(!n\)分解質因數

\(code:\)

//prime[i]存了1-n範圍內的所有質數

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

那麼我們就能分解質因數了。先線性篩法預處理\(2n\)範圍內的所有質數,然後迴圈列舉每乙個質因子,對於每乙個質因子,我們借助如上規律累乘質因子\(p\),再累加每乙個\(\lfloor\frac\rfloor\)即可得到因子\(p\)在\(!(2n)\)的分解式中的指數大小,從而得到\(!(2n)\)的分解式。

同理,我們可以繼續用這種方法分解\((!n)^2\),再將相同因子的質數減去即可。

對於\(n+1\),我們直接暴力分解一下,將相同因子的質數減去,就得到了最終答案的分解式,然後快速冪配合高精度乘法做一下就可以了。

\(code:\)

#includeusing namespace std;

const int base=1e8,maxlen=1e4;

struct bign

inline void print(void)

bign operator = (int a)

while(a);

return *this;

} bign operator * (bign a)

if(temp)

res.d[i+a.len]=temp;

} res.len=len+a.len;

while(!res.d[res.len]&&res.len>1)res.len--;

return res;

}};//結構體封裝的大整數高精度

const int n=65000+20;

int n,vis[n*2],prime[n*2],cnt,p[n*2],a[n*2],reto[n*2],tot;

inline void sieve(void) }}

inline long long power(long long a,long long b)

return res;

}inline void solve(void)

//分解!n

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

//暴力分解一下n+1

int m=n+1;

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

//將指數減去

a[reto[prime[i]]]-=sum;

} }bign ans,temp;

ans=1;

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

ans.print();

}int main(void)

《後記》

棧 卡特蘭數 火車進出棧問題

傳送門 題意 一列火車n節車廂,依次編號為1,2,3,n。每節車廂有兩種運動方式,進棧與出棧,問n節車廂出棧的可能排列方式有多少種。資料範圍 1 n 60000 輸入樣例 3輸出樣例 5思路 進出棧問題 序列問題 路徑問題。這顯然是上一道火車進棧的公升級版,資料太大不能再進行遞迴處理了。問題轉換 尋...

卡特蘭數問題

卡特蘭陣列 1,1,2,5,14,42,132 公式 f n f 0 f n 1 f 1 f n 2 f n 1 f 0 c 2n,n n 1 c 2n,n c 2n,n 1 f 0 1,f 1 1,f 2 2,f 3 5 已知進棧順序abcd,那麼可能的出棧順序多少種?答案 f 4 14 解析 以...

火車進出站問題 棧

編號為1,2,n的n輛火車依次進站,給定乙個n的排 列,判斷是否是合法的出站順序?思路 先把出站順序存入,用棧模擬進站的火車,按照出站的順序,依次pop出來,判斷 最後的出站數量能否達到n。include include include using namespace std const int m...