1. 程式人生 > >【BZOJ 4766】文藝計算姬

【BZOJ 4766】文藝計算姬

【題目】

傳送門

題目描述:

“奮戰三星期,造臺計算機”。小 W 響應號召,花了三星期造了臺文藝計算姬。

文藝計算姬比普通計算機有更多的藝術細胞。 普通計算機能計算一個帶標號完全圖的生成樹個數,而文藝計算姬能計算一個帶標號完全二分圖的生成樹個數。

更具體地,給定一個一邊點數為 n n ,另一邊點數為 m

m ,共有 n m n*m 條邊的帶標號完全二分圖 k n
, m k_{n,m}
,計算姬能快速算出其生成樹個數。

小 W 不知道計算姬算的對不對,你能幫助他嗎?

輸入格式:

僅一行三個整數 n , m

, p n,m,p ,表示給出的完全二分圖 k n , m k_{n,m}

輸出格式:

僅一行一個整數,表示完全二分圖 k n , m k_{n,m} 的生成樹個數,答案需要模 p p

樣例資料:

輸入
2 3 7

輸出
5

備註:

【資料範圍】
20% 的資料: n m 20 n*m ≤ 20
另有 10% 的資料: n = 2 n=2
另有 20% 的資料: n = 3 , m 1 0 6 n=3 , m≤10^6
另有 20% 的資料: n = 4 n=4
100% 的資料: 1 n , m , p 1 0 18 1 ≤n,m,p ≤ 10^{18}


【分析】

直接說結論吧,最後的答案 a n s = m n 1 n m 1    m o d    p ans=m^{n-1}\cdot n^{m-1} \;mod\;p

當然,這個東西我是沒有推出來的,我們老師直接給我們說了結論,讓我們當成快速冪板子做

注意兩個 l o n g    l o n g long\;long 相乘很可能會爆 l o n g    l o n g long\;long 的範圍,我們要用快速積來防止爆精度


【程式碼】

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long n,m,p;
long long Multiply(long long a,long long b,long long c)
{
	long long ans=0,res=a;
	while(b)
	{
		if(b&1)
		  ans=(ans+res)%c;
		res=(res+res)%c;
		b>>=1;
	}
	return ans;
}
long long Power(long long a,long long b,long long c)
{
	long long ans=1,res=a;
	while(b)
	{
		if(b&1)
		  ans=Multiply(ans,res,c);
		res=Multiply(res,res,c);
		b>>=1;
	}
	return ans;
}
int main()
{
	scanf("%lld%lld%lld",&n,&m,&p);
	printf("%lld",Multiply(Power(n,m-1,p),Power(m,n-1,p),p));
	return 0;
}