[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,然后需要“快速乘”。

posted @ 2017-03-10 16:15  xjr01  阅读(271)  评论(0编辑  收藏  举报