poj 3233 Matrix Power Series (構造分塊矩陣)
阿新 • • 發佈:2018-12-15
題目連結:哆啦A夢傳送門
題意:自己看。
參考部落格:神犇
題解:分塊矩陣:分塊矩陣可以構造求和。
例如:我們可以這樣構造,
還需注意一點的是:算完S(k+1),取出右上角矩陣分塊後,還需減掉單位矩陣E。
程式碼不是我寫的,我就按自己習慣改了下變數,主要是博主寫的太溜了,不搬都對不起他:
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long LL; LL mod; int n,k; struct mat{ LL a[70][70]; mat(){ memset(a,0,sizeof(a));} mat operator * (const mat y) { mat ans; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) ans.a[i][j]=(ans.a[i][j]+a[i][k]*y.a[k][j])%mod; return ans; } mat operator + (const mat y) { mat ans; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) ans.a[i][j]=(ans.a[i][j]+y.a[i][j])%mod; return ans; } }; mat mat_pow(mat x,int k) { mat ans; for(int i=1;i<=n;i++) ans.a[i][i]=1; while(k) { if(k&1) ans=ans*x; x=x*x; k>>=1; } return ans; } int main() { while(~scanf("%d%d%lld",&n,&k,&mod)) { mat p; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++){ scanf("%lld",&p.a[i][j]); ///左上角矩陣 p.a[i][j]%mod; } p.a[i+n][i+n]=1; ///構造右下角單位陣 p.a[i][i+n]=1;///構造左上角單位陣 } n<<=1; mat item=mat_pow(p,k+1); n>>=1; mat ans; for(int i=1;i<=n;i++) for(int j=n+1;j<=n*2;j++) ///把右上角的矩陣分塊取出 ans.a[i][j-n]=item.a[i][j]; for(int i=1;i<=n;i++){ ans.a[i][i]--; ///減去單位矩陣 if(ans.a[i][i]<0) ans.a[i][i]+=mod; } for(int i=1;i<=n;i++) ///輸出 { for(int j=1;j<=n;j++) printf("%lld ",ans.a[i][j]); puts(""); } } return 0; }
我的標籤:做個有情懷的程式設計師。