題目傳送門
題目大意:問有多少個長度為 2n2n
2n的序列滿足以下條件:1、這個序列是 1
11 ~ 2n2n
2n的乙個排列;2、這個序列奇數字遞增,偶數字也遞增;3、每個偶數字比在他前面一位的奇數字要大。
我們設這個序列為 aaa。
發現這樣乙個性質:每個偶數字 2i2i
2i滿足a2i
>a2
i−
2>a2
i−
4>a2
i−
6>..
.a2i
>a2
i−
1>a2
i−
3>a2
i−
5>..
.a_>a_>a_>a_>...\\ a_>a_>a_>a_>...\\
a2i
>a2
i−2
>a2
i−4
>a2
i−6
>..
.a2i
>a2
i−1
>a2
i−3
>a2
i−5
>..
. 也就是說,每個偶數字比它前面的所有位都大,那麼就說明,每個偶數字上放的數大於等於這個位置的下標。
然後考慮將 1
11 ~ 2n2n
2n這些數依次加入到這個序列裡面,每次加入的位置只能是此時的偶數字最前面一位,或奇數字最前面一位。
我們設此時放了 1
11 ~ p
pp 這些數,其中在奇數字上放了 x
xx 個,在偶數字上放了 y
yy 個。發現乙個性質:對於任意 p
pp,都有 x≥y
x\geq y
x≥y。
證明:考慮用反證法,假設對於某個 p
pp,有 y
>
xy>x
y>x。
∵ x+
y=p,
y>
x\because x+y=p,y>x
∵x+y=p
,y>x∴
y>p2
\therefore y>\frac p 2
∴y>2p∴2
y>
p\therefore 2y>p
∴2y>p
因為偶數字上放了 y
yy 個,最後放的那個偶數字的下標為 2y2y
2y,我們上面要求這個位置放的數大於等於 2y2y
2y,但是此時只放了 1
11 ~ p
pp,而 p
<2y
p<2y
p<2y
,所以不可能存在 y
>
xy>x
y>
x 的情況。
那麼就變成 2n2n
2n個數,每個數可以往最前面的奇數字放或往最前面的偶數字放,要求對於任意時刻,往奇數字上放的數的數量都大於等於往偶數字上放的數的數量,問有多少種放的方法。
因為奇數字只有 n
nn 個,偶數字也只有 n
nn 個,那麼轉化一下,設往奇數字上放為 1
11,往偶數字上放為 0
00,那麼問題變成:將 n
nn 個 0
00 和 n
nn 個 1
11 進行排列,要求對於任意字首都有 1
11 的數量大於等於 0
00 的數量。
誒,這不就是乙個卡特蘭數嘛!
由於題目不給你模數,所以求的時候要對每個數質因數分解存下來,最後再乘起來取模輸出。
質因數分解有個小技巧:可以先篩出所有質數,對於每個數,從小的質數往大的質數遍歷,假如找到了它的質因數就除掉,這樣是比 o(n
)o(\sqrt n)
o(n
) 的做法要快的。
但是這種做法有個不優秀的地方,假如我們要分解的數就是個質數,那麼根本沒必要判斷那麼多次,所以我們在迴圈時再判斷一下當前這個數是個質數的情況就會快很多。
**如下:
#include
#include
#define maxn 2000010
#define ll long long
int n,p;
int prime[maxn]
,t=0
;bool v[maxn]
;int tot[maxn]
;void
work()
}}void
add(
int x,
int p)
if(x==1)
break;}
}ll ksm
(int x,
int y)
return re;
}int
main()
HNOI2009 有趣的數列
求 1 到 2n 的全排列種類數,滿足奇數項和偶數項分別單增,任意 a a 以下為亂搞。考慮從1開始考慮每個數字怎麼填,可以看 猜 出,由於相鄰偶數項比奇數項大,所以奇數項一定要小一些,所以奇數項填的數字個數一定始終大於等於偶數項,這就是個卡特蘭數啦 問題變成求 catlan n p 由於 p 不是...
HNOI2009 有趣的數列 卡特蘭數與楊表
我們稱乙個長度為2n的數列是有趣的,當且僅當該數列滿足以下三個條件 1 它是從1到2n共2n個整數的乙個排列 2 所有的奇數項滿足a1 3 2n 1,所有的偶數項滿足a2 4 2n 3 任意相鄰的兩項a2i 1與a2i 1 i n 滿足奇數項小於偶數項,即 a2i 1 2i。現在的任務是 對於給定的...
1485 HNOI2009 有趣的數列
題目鏈結 題目大意 稱乙個長度為2n 的數列是有趣的,當且僅當該數列滿足以下三個條件 它是乙個1 2n的排列a1 n 1,a2 n a2 i 1i 題解 丟題解跑qaq 我的收穫 2333 include using namespace std define maxn 3000005 int n,p...