提高組(計數)

2022-09-17 00:30:12 字數 1816 閱讀 8483

題目鏈結

類題:氣泡排序

求長度為 \(n\) 的排列中滿足最長下降子串行長度不超過 2 ,且符合\(p_x=y\) 的排列數。\(n \le 10^7,t \le 10^6\)

題意轉化:不存在三個點,使得左邊的點比中間大,右邊的點比中間小。

我們要知道乙個 trick : 從大到小/從小到大列舉數,嘗試將其插入當前排列,並使之合法。這樣的話我們在插入的時候只需要保證如果前面有比它大的的話,以後比它小的就不能放後邊了。由於我們從大到小放,當前序列上的數都比他大,之後的數都比他小,於是我們要麼放最前面,要麼放到某個位置,並且要求以後放的數都要在它之前。

我們發現這可能會有乙個「只能放在前 \(j\) 個數之後」的限制。於是設定dp狀態:\(f_\) 表示已經放了 \(i\) 個數,要求以後只能放在前 \(j\) 個數之後(或者最前面)的方案數,那麼轉移就比較顯然了:

放最前面:

\[f_ \to f_

\]放第 \(k\) 個的後面:

\[f_ \to f_,k\le j

\]總的來說:

\[f_ \to f_,k\le j+1

\]如果我們在一張網格圖上看,這像是網格圖上的路徑;經過一些轉化,我們發現轉移其實就是只能向右上走,且不能穿過 \(y=x\) 的一條條路徑,一次轉移相當於向右走一步,再向上走若干步。

然後題目還要求 \(p_x=y\)。如果 \(x=y\),那麼第 \(x\) 個之前一定都是比 \(y\) 小的,第 \(x\) 個之後一定都是比 \(y\) 大的。直接單獨用卡特蘭數算後乘起來即可。

如果 \(x > y\),那麼我們在放第 \(y\) 小的數的時候就不能讓它放到最前面了,否則僅剩的 \(y-1\) 個數不足以支援其成為第 \(x\) 個數。那麼他只能放到某乙個數的後面,這樣的話以後比他小的數就都會放到他的前面,那麼這個數到底插到第幾個數的後面就知道了,即能算出乙個數 \(k\),使得所有第 \(x-1\) 列的狀態都要轉移到 \(f_\)。然後問題轉化為了乙個網格圖上必經一點的「卡特蘭數」,亦用翻摺法可解(根據 \(y=x+1\) 對稱)。

如果 \(x < y\),看起來它是可以放到最前面的,並且對以後的影響也不太好處理。不過這種問題實際上可以轉化為 \(x \gets n - x + 1, y \gets n - y + 1\) 的問題(全部取反後成為反向問題)

下面給出一些關鍵引數:

由dp轉化為「卡特蘭數」網格圖的方法:

\[(x,y) \to (x-1, x-y)

\]這種轉化方法將「放在最前面」對映成了橫著走

必經的那個點:

\[(n-y,n-x+1)

\]根據 \(y=x+1\) 翻摺:

\[(x,y) \to (y-1,x+1)

\]路徑:

\[(0,0) \to (n-y,n-x+1) \to (n,n)

\]注意,我們不僅要求經過一點,還要求經過前一步不能橫著走過來,經過的後一步要先向右走一步。

關鍵**:

inline ll calc(int n, int m) 

inline void work()

if (x < y) x = n - x + 1, y = n - y + 1;

ll ans = (calc(n - y, n - x + 1) - (x == y + 1 ? 0 : calc(n - y - 1, n - x + 1))) * (get_c(y-1+x-1,y-1) - get_c(y-2+x,x)) % p;

//attention!!!

printf("%lld\n", (ans % p + p) % p);

}

計數 NOIP2016提高A組模擬7 15

樣例輸入 2 10 樣例輸出 90資料範圍 剖解題目 題目說的很明了了。思路 求方案數,一般會設計道dp,規律之類的。解法 數字dp,設f i j 表示當前到了第i位,這一位的數字是j的方案數。自然有 f i j f i 1 l f i j 0 l k 且 l 0 and j 0 看到這位數,很明顯...

NOIP2017提高A組模擬9 7 計數題

這題很有趣 首先那些邊權都為0的,就是完全圖的生成樹個數,為nn 2按照二進位制從最高位開始做 每次按照0 1分制,會得到兩棵生成樹,一棵全是這位為0,一棵全是這位為1 然後選一條最短的邊連線兩邊,這個用字典樹搞定 然後就沒了 include include include include defi...

2018 07 08 2018提高組 模擬C組

fj準備教他的奶牛彈奏一首歌曲,歌曲由n 1 n 50,000 種音節組成,編號為1到n,而且一定按照從1到n的順序進行彈奏,第i種音節持續b i 1 b i 10,000 個節拍,節拍從0開始計數,因此從節拍0到節拍b 1 1彈奏的是第1種音節,從b 1到b 1 b 2 1彈奏的是第2種音節,依此...