[BZOJ4766]文艺计算姬
[BZOJ4766]文艺计算姬
试题描述
"奋战三星期,造台计算机"。小W响应号召,花了三星期造了台文艺计算姬。文艺计算姬比普通计算机有更多的艺术细胞。普通计算机能计算一个带标号完全图的生成树个数,而文艺计算姬能计算一个带标号完全二分图的生成树个数。更具体地,给定一个一边点数为n,另一边点数为m,共有n*m条边的带标号完全二分图K_{n,m},计算姬能快速算出其生成树个数。小W不知道计算姬算的对不对,你能帮助他吗?
输入
仅一行三个整数n,m,p,表示给出的完全二分图K_{n,m}
1 <= n,m,p <= 10^18
输出
仅一行一个整数,表示完全二分图K_{n,m}的生成树个数,答案需要模p。
输入示例
2 3 7
输出示例
5
数据规模及约定
见“输入”
题解
矩阵树定理,当科普一下吧。。。
构造出基尔霍夫矩阵的主子式,然后算行列式打表找规律。
答案是 nm-1 · mn-1,我并不会证。。。。。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <algorithm> #include <cmath> using namespace std; #define LL long long LL read() { LL x = 0, f = 1; char c = getchar(); while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); } while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); } return x * f; } LL n, m, p; LL Mul(LL a, LL b) { LL ans = 0, t = a; while(b) { if(b & 1) (ans += t) %= p; (t += t) %= p; b >>= 1; } return ans; } LL Pow(LL a, LL b) { LL ans = 1, t = a; while(b) { if(b & 1) ans = Mul(ans, t); t = Mul(t, t); b >>= 1; } return ans; } int main() { n = read(); m = read(); p = read(); printf("%lld\n", Mul(Pow(n, m - 1), Pow(m, n - 1))); return 0; }
读入开 long long,然后需要“快速乘”。