我們稱乙個長度為 2n 的數列是有趣的,當且僅當該數列滿足以下三個條件:
它是從 1 到 2n 共 2n 個整數的乙個排列 ;
所有的奇數項滿足 a
1 < ⋯ n− 1a_1a1 < ⋯n−1 ,所有的偶數項滿足 a 2 < ⋯ na_2a2 < ⋯n;任意相鄰的兩項 a2i −1 a_a2 i−1 與 a2ia_ a2i (1 ≤i ≤n 1≤i≤n 1≤i≤ n) 滿足奇數項小於偶數項,即:a2i −1 ia_a2 i−1 i。任務是:對於給定的 n,請求出有多少個不同的長度為 2n 的有趣的數列。 因為最後的答案可能很大,所以只要求輸出答案 modp 的值。 輸入格式 只包含用空格隔開的兩個整數 n 和 p。 輸出格式 僅含乙個整數,表示不同的長度為 2n 的有趣的數列個數 modp 的值。 資料範圍 1≤n≤106, 2≤p≤109 輸入樣例: 3 10 輸出樣例: 5樣例解釋 對應的 5 個有趣的數列分別為 ,,,,。 看到3,5的時候就應該往卡特蘭數那個方向想了。首先我們回憶下卡特蘭數的性質:滿足…序列中…的個數都不少於…的個數的序列有多少個。然後我們看這道題的擺列方式。寫幾個數可以發現1的位置一定是確定在奇數項位置的。然後再看後面的拜訪的時候,擺放的時候奇數項的個數一定要大於等於偶數項的個數,比如放5的時候,如果奇數項小於偶數項,那麼5前面的偶數項一定要小於等於奇數項,不然這其中的偶數項就會是5後面的某個數(比5大)。就不滿足情況了。 這裡因為p不是質數,所以我們直接用c2n n−c2 nn−1 =c2n n/n+ 1c_^n-c_^=c_^n/n+1 c2nn− c2nn −1= c2nn /n+ 1的前半部分來算,求組合數的時候用分解質因子+快速冪來求。 #define int long long using namespace std; const int n= 2000010 ;int n,p,prime[n] ,cnt,st[n] ;void init (int n)}} intget (int a, int b) intq_pow (int a, int k) return res; }intc( int a, int b) return (res+p) %p;} signed main() 對於求組合數,要根據所給資料範圍來選擇合適的演算法 這道題中所給的資料範圍適合用打表的方法直接暴力求解 先用4e6的複雜度預處理出所有的情況,再用1e4的複雜度完成詢問即可 include using namespace std const int n 2010 const int mod 1e9 ... mod must be a prime const int mod 1e9 7 namespace combinatory ll inv ll x ll fac maxn invfac maxn void initc int n ll a ll n,ll m ll c ll n,ll m ll d ... 從n個數中選m個數,每個數至多選一次,方案數 性質 c n,0 c n,n 1 c n,m c n,n m c n,m c n 1,m 1 c n 1,m 楊輝三角 二項式展開 x y n i 0.n c n,i x iy n i 那這裡先說一下楊輝三角 前提 每行端點與結尾的數為1 每個數等於它上...#include
組合數學 求組合數
數學 組合數學
組合數學筆記