1. 程式人生 > >BZOJ4766:文藝計算姬(矩陣樹定理)

BZOJ4766:文藝計算姬(矩陣樹定理)

Description

"奮戰三星期,造臺計算機"。小W響應號召,花了三星期造了臺文藝計算姬。文藝計算姬比普通計算機有更多的藝術細胞。 普通計算機能計算一個帶標號完全圖的生成樹個數,而文藝計算姬能計算一個帶標號完全二分圖的生成樹個數。 更具體地,給定一個一邊點數為n,另一邊點數為m,共有n*m條邊的帶標號完全二分圖K_{n,m},計算姬能快速算出其生成樹個數。 小W不知道計算姬算的對不對,你能幫助他嗎?

Input

僅一行三個整數n,m,p,表示給出的完全二分圖K_{n,m} 1 <= n,m,p <= 10^18

Output

僅一行一個整數,表示完全二分圖K_{n,m}的生成樹個數,答案需要模p。

Sample Input

2 3 7

Sample Output

5

Solution

首先先把(度數矩陣-鄰接矩陣)搞出來,這裡以樣例為例。
$
\left\{
\begin{matrix}
3&0&-1&-1&-1\\
0&3&-1&-1&-1\\
-1&-1&2&0&0\\
-1&-1&0&2&0\\
-1&-1&0&0&2\\
\end{matrix}
\right\}
$
按照求矩陣樹的方法隨便刪掉一行一列,這裡刪掉了最後一行和最後一列。
$
\left\{
\begin{matrix}
3&0&-1&-1\\
0&3&-1&-1\\
-1&-1&2&0\\
-1&-1&0&2\\
\end{matrix}
\right\}
$
把前$n-1$行和後$m-1$行都加到第$n$行
$
\left\{
\begin{matrix}
3&0&-1&-1\\
1&1&0&0\\
-1&-1&2&0\\
-1&-1&0&2\\
\end{matrix}
\right\}
$
用第$n$行的去加到後面$m-1$行上,把$-1$給消掉。
$
\left\{
\begin{matrix}
3&0&-1&-1\\
1&1&0&0\\
0&0&2&0\\
0&0&0&2\\
\end{matrix}
\right\}
$

這樣的話這個矩陣的行列式顯然就是$m^{n-1}n^{m-1}$了。
記得快速乘。

Code

 1 #include<cstdio>
 2 #define LL long long 
 3 using namespace std;
 4 
 5 LL n,m,p;
 6 
 7 LL Mul(LL a,LL b)
 8 {
 9     LL tmp=a*b-(LL)((long double)a*b/p+0.1)*p;
10     return tmp<0?tmp+p:tmp;
11 }
12 
13 LL Qpow(LL a,LL b)
14 {
15     LL ans=1;
16     while (b)
17
{ 18 if (b&1) ans=Mul(ans,a); 19 a=Mul(a,a); b>>=1; 20 } 21 return ans; 22 } 23 24 int main() 25 { 26 scanf("%lld%lld%lld",&n,&m,&p); 27 printf("%lld",Mul(Qpow(n,m-1),Qpow(m,n-1))); 28 }