2018.10.15【BZOJ4766】文藝計算姬(矩陣快速冪)(矩陣樹)(prufer序列)(結論題)
阿新 • • 發佈:2019-01-03
傳送門
解析:
顯然可以用來做 推導。
思路:
我們直接建出基爾霍夫矩陣,顯然我們可以把它分成四塊:
左上角為是一個的對角線為的矩陣,其餘為0。
右上角為是一個的全部為的矩陣
左下角為是一個的全部為的矩陣,即矩陣的轉置
右下角為是一個的對角線為的矩陣,其餘為0。
把矩陣推導一下:
那麼就顯然是。
後面的再推一下。
是的逆,規模相同,對角線為。
那麼這一坨就可以推出了:是一個規模為,所有元素為的矩陣。
後面一大坨就直接作差得到一個矩陣,的對角線上全部是,其餘部分是,規模為。
我們直接把提出來得到新的矩陣,的對角線就全部都是,其餘部分全部都是。
這個。。。
好的這道題做完了。
這個對應的基爾霍夫矩陣求的就是有 個節點的無向完全圖的生成樹個數 。由序列瞎推一波可以知道生成樹個數就是
再把剛才提出來的和原來的乘回去就可以知道我們要求的東西了
trick:
直接乘肯定會爆,考場上又不可能用__int128。
所以去學習一下龜速乘吧。
程式碼:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline ll getint(){
re ll num;
re char c;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return num;
}
ll mod;
inline ll mul(ll a,ll b){
return (a*b-(ll)((long double)a/mod*b)*mod+mod)%mod;
/* ll ans=0;
while(b){
if(b&1)ans=(ans+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return ans;*/
}
inline ll quickpow(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=mul(ans,a);
a=mul(a,a);
b>>=1;
}
return ans;
}
ll n,m;
signed main(){
n=getint(),m=getint(),mod=getint();
cout<<(ll)mul(quickpow(n,m-1),quickpow(m,n-1));
return 0;
}