Description
“奋战三星期,造台计算机”。小W响应号召,花了三星期造了台文艺计算姬。文艺计算姬比普通计算机有更多的艺
术细胞。普通计算机能计算一个带标号完全图的生成树个数,而文艺计算姬能计算一个带标号完全二分图的生成树
个数。更具体地,给定一个一边点数为n,另一边点数为m,共有n*m条边的带标号完全二分图K_{n,m},计算姬能快
速算出其生成树个数。小W不知道计算姬算的对不对,你能帮助他吗?
1 <= n,m,p <= 10^18
Solution
设D为图的度数矩阵,即D[i,i]=i的度数,其余都为0
设A为图的邻接矩阵,即A[i,j]=i到j的边数,其余都为0
那么基尔霍夫矩阵K=D-A
去掉矩阵K中的任意一行任意一列后用类似高斯消元的方法求出对角线的乘积的绝对值就是基尔霍夫矩阵的行列式,等同于图的生成树计数
暂时还没有找到裸题搞一搞,就写了这个
在这道题里面可以打个表或者写个矩阵推一推,发现ans=nm−1mn−1ans=nm−1mn−1,那么快速幂+ll乘就行了
似乎还能用prufer编码证明,但是我不会呀qaq
Code
#include <stdio.h>
#include <string.h>
typedef long long LL;
LL n,m,p;
LL mul(LL a,LL b) {
LL tmp=a*b-(LL)((long double)a*b/p+0.1)*p;
if (tmp<0) tmp+=p;
return tmp;
}
LL ksm(LL x,LL dep,LL p) {
if (dep==0) return 1;
if (dep==1) return x%p;
LL tmp=ksm(x,dep/2,p); tmp=mul(tmp,tmp);
if (dep&1) return mul(tmp,x);
return tmp;
}
int main(void) {
scanf("%lld%lld%lld",&n,&m,&p);
LL a=ksm(n%p,m-1,p);
LL b=ksm(m%p,n-1,p);
LL ans=mul(a,b);
printf("%lld\n", ans);
return 0;
}