说在前面
并没有什么想说的,但是要保持格式=w=
题目
题目大意
<n,m>
<
n
,
m
>
<script type="math/tex" id="MathJax-Element-56">
</script>的完全二分图生成树计数,对
P
P
取模
输入输出格式
输入格式:
输入三个数字,
n,m,P
n
,
m
,
P
,含义如题
输出格式:
输出一个整数表示答案
解法
用Matrix-tree定理,把基尔霍夫矩阵搞出来,然后直接手动高消即可
贴两篇题解:CRZbulabula,sengxian
另外,还可以用Prufer编码证明此题公式
显然最后两侧会各留下一个点,所以一边会被加入
n−1
n
−
1
次,另一边会被加入
m−1
m
−
1
次。
考虑一下,如果同侧序列的内部顺序已经确定,那么两侧的相对位置随之确定(因为解码Prufer的时候需要保证同侧无边,所以随着解码的进行,相对位置就被确定下来了,可以手动模拟几组数据感受一下)
所以,只需要分别确定内部顺序,再把内部顺序方案数相乘即可,显然答案是
nm−1mn−1
n
m
−
1
m
n
−
1
下面是代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
long long N , M , P ;
long long s_mul( long long x , long long y ){
long long rt = 0 ;
while( y ){
if( y&1 ) rt = ( rt + x )%P ;
x = ( x + x )%P , y >>= 1 ;
} return rt ;
}
long long s_pow( long long x , long long y ){
long long rt = 1 ;
while( y ){
if( y&1 ) rt = s_mul( rt , x ) ;
x = s_mul( x , x ) , y >>= 1 ;
} return rt ;
}
int main(){
scanf( "%lld%lld%lld" , &N , &M , &P ) ;
printf( "%lld" , s_mul( s_pow( N%P , M - 1 ) , s_pow( M%P , N - 1 ) ) ) ;
}