[BZOJ4766]文藝計算姬(矩陣+矩陣樹定理+快速加)
阿新 • • 發佈:2019-02-19
題目:
題解:
完全二分圖:X中的任一頂點與Y中每一個頂點均有且僅有唯一的一條邊相連
不難發現K矩陣是長這個樣子的
我們對這個矩陣分一下塊,左上角是n * n的對角線為m的矩陣A,右上角是全為-1的n * (m-1)的矩陣B,左下角是全為-1的(m-1) * n的矩陣C,右下角是對角線為n的(m-1)*(m-1)的矩陣設為D
分塊矩陣的行列式求法:
A 0
0 B
行列式為|A||B|
0 A
B 0
行列式為(-1)^(mn)|A||B|
A B
C D
行列式為|A||D-C*A^(-1)*B|
這個矩陣的|A|顯然是m^n
後面為A的逆矩陣,是一個主對角線為1/m,其餘值為0的矩陣
逆矩陣:A的逆矩陣為與A相乘得單位矩陣的矩陣
單位矩陣:主對角線為1,其餘為0的矩陣
可逆矩陣:有逆矩陣的矩陣,可以通過|A|!=0判斷
可以發現後面的矩陣為
即主對角線為n-n/m,其餘為-n/m的矩陣
然而打表找規律才是這道題目的正確開啟方式
這道題目需要用快速乘,而且快速冪的時候也要快速乘,不然GG
題解中部分圖片引自dalao,侵刪
程式碼:
#include <cstdio>
#define LL long long
using namespace std;
LL n,m ,p;
LL ksc(LL a,LL k)
{
LL ans=0;
for (;k;k>>=1,a=2ll*a%p)
if (k&1) ans=(ans+a)%p;
return ans;
}
LL ksm(LL a,LL k)
{
LL ans=1; a%=p;
for (;k;k>>=1,a=ksc(a,a))
if (k&1) ans=ksc(ans,a);
return ans;
}
int main()
{
scanf("%lld%lld%lld",&n,&m ,&p);
printf("%lld",ksc(ksm(n,m-1),ksm(m,n-1)));
}