題目描述稱乙個1,2
,...
,n
1,2,...,n
1,2,..
.,n的排列p1,
p2..
.,pn
p_1,p_2...,p_n
p1,p2
...
,pn
是magic的,當且僅當2
<=i
<=n
2<=i<=n
2<=i
<=n
時,p
i>pi
/2
p_i>p_
pi>pi
/2. 計算1,2
,...
n1,2,...n
1,2,..
.n的排列中有多少是magic的,答案可能很大,只能輸出模p以後的值
輸入格式
輸入檔案的第一行包含兩個整數 n和p,含義如上所述。
輸出格式
輸出檔案中僅包含乙個整數,表示計算1,2
,⋯,n
1,2,⋯, n
1,2,⋯,
n的排列中, magic排列的個數模 p
pp的值。
輸入輸出樣例輸入 #1
20 23
輸出 #116
說明/提示100
100%
100的資料中,1≤n
≤106
,p≤1
09,p
1 ≤n ≤ 10^6, p≤ 10^9,p
1≤n≤10
6,p≤
109,
p是乙個質數。
解釋:由pi>pi
/2
p_i>p_
pi>pi
/2性質,我們可以畫出拓撲結構,大約和完全二叉樹是一樣的,所以我們可以先dp出,滿完全二叉樹,的全排列組合數即dp[
i]=d
p[i−
1]2∗
c2i−
22i−
1−
1dp[i]=dp[i-1]^2*c_^-1}
dp[i]=
dp[i
−1]2
∗c2i
−22i
−1−1
,其中i
ii為高度為i
ii,然後我們可以遞迴的分解樹,每碰到乙個滿完全二叉樹,就直接返回dp[
i]
dp[i]
dp[i
]
#includeusing namespace std;
long long fact[2000003]=;
long long n=0,p=1000000009;
long long pow(long long a,long long b)
return ret;
}long long dp[30]=;
long long mi=8;
long long c(long long n,long long m)
int check(int x)
if(sum<=1) return num-1;
else return 0;
}long long ok(int n)else
return c(n-1,b)*ok(a)%p*ok(b)%p;
}int main()
cout
}
題解 P2606 ZJOI2010 排列計數
題目鏈結 題目大意 求 1 n 的排列 p 中,有多少個排列滿足 forall i in 2,n p i p rfloor 對給定質數 m 取模。分析 p i p rfloor 反過來 forall x,p x,那麼問題變成一棵 n 個節點的完全二叉樹,將數 1 n 分配給每乙個節點,使得每個父節點...
P2606 ZJOI2010 排列計數 分析
題意可以簡化為用 1,n 的數,組成乙個完全二叉樹,使其滿足小根堆性質,求方案數。令 f i 表示在 i 點的方案數,s i 表示 i 的子節點個數 包括 i 於是得出遞推式 f i c times f times f 由於 bzoj 上 n m 可能 所以需要用 lucas 定理。namespac...
洛谷P2602 ZJOI2010 數字計數 題解
很裸的一道數字dp的板子 定義f 當前列舉到的數字 當前數字之前的答案 列舉的數字 其它的套板子就可以了,要注意一下字首0的判斷 1 include2 include3 include4 include5 include6 include7 using namespace std 8 typedef...