文艺计算姬
Time Limit: 1 Sec Memory Limit: 128 MB[Submit][Status][Discuss]
Description
"奋战三星期,造台计算机"。
小W响应号召,花了三星期造了台文艺计算姬。
文艺计算姬比普通计算机有更多的艺术细胞。
普通计算机能计算一个带标号完全图的生成树个数,而文艺计算姬能计算一个带标号完全二分图的生成树个数。
更具体地,给定一个一边点数为n,另一边点数为m,共有n*m条边的带标号完全二分图K_{n,m},计算姬能快速算出其生成树个数。
小W不知道计算姬算的对不对,你能帮助他吗?
小W响应号召,花了三星期造了台文艺计算姬。
文艺计算姬比普通计算机有更多的艺术细胞。
普通计算机能计算一个带标号完全图的生成树个数,而文艺计算姬能计算一个带标号完全二分图的生成树个数。
更具体地,给定一个一边点数为n,另一边点数为m,共有n*m条边的带标号完全二分图K_{n,m},计算姬能快速算出其生成树个数。
小W不知道计算姬算的对不对,你能帮助他吗?
Input
仅一行三个整数n,m,p,表示给出的完全二分图K_{n,m}
Output
仅一行一个整数,表示完全二分图K_{n,m}的生成树个数,答案需要模p。
Sample Input
2 3 7
Sample Output
5
HINT
1 <= n,m,p <= 10^18
Main idea
询问带标号的完全二分图生成树个数。
Solution
我们简单地用矩阵树定理以及各种公式(用观察法得到)证明出答案等于:
然后我们暴力写一个快速幂即可,又由于p<=10^18,两数相乘会爆long long,我们再用类似快速幂的方法写一个慢速乘来做乘法即可。
Code
1 #include<iostream>
2 #include<algorithm>
3 #include<cstdio>
4 #include<cstring>
5 #include<cstdlib>
6 #include<cmath>
7 using namespace std;
8 typedef unsigned long long ull;
9 typedef long long s64;
10
11 s64 n,m,MOD;
12
13 s64 Slowcheng(s64 a,s64 b)
14 {
15 s64 res=0;
16 while(b)
17 {
18 if(b&1) res=((ull)res+a)%MOD;
19 a=((ull)a+a)%MOD;
20 b>>=1;
21 }
22 return res;
23 }
24
25 s64 Quickpow(s64 a,s64 b)
26 {
27 s64 res=1;
28 while(b)
29 {
30 if(b&1) res=(ull)Slowcheng(res,a);
31 a=(ull)Slowcheng(a,a);
32 b>>=1;
33 }
34 return res;
35 }
36
37 int main()
38 {
39 cin>>n>>m>>MOD;
40 printf("%lld", Slowcheng(Quickpow(n,m-1) , Quickpow(m,n-1)));
41 }