题目背景
矩阵快速幂
题目描述
给定 n×nn imes nn×n 的矩阵 AAA,求 AkA^kAk。
输入格式
第一行两个整数 n,kn,kn,k 接下来 nnn 行,每行 nnn 个整数,第 iii 行的第 jjj 的数表示 Ai,jA_{i,j}Ai,j。
输出格式
输出 AkA^kAk
共 nnn 行,每行 nnn 个数,第 iii 行第 jjj 个数表示 (Ak)i,j(A^k)_{i,j}(Ak)i,j,每个元素对 109+710^9+7109+7 取模。
输入输出样例
输入 #1
2 1 1 1 1 1
输出 #1
1 1 1 1
说明/提示
【数据范围】
对于 100%100\%100% 的数据:1≤n≤1001le n le 1001≤n≤100,0≤k≤10120 le k le 10^{12}0≤k≤1012, ∣Ai,j∣≤1000|A_{i,j}| le 1000 ∣Ai,j∣≤1000
https://www.luogu.com.cn/problem/P3390
#include<cstdio> #include<iostream> #include<algorithm> #include<map> #include<bits/stdc++.h> #include <math.h> using namespace std; typedef long long ll; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=5e5+10; const int mod=1e9+7; ll n,k; struct node{ ll a[110][110]; }p,pp;//p代表读入矩阵,pp代表输出矩阵 node qu(node x,node y){//返回一个矩阵 node box; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ box.a[i][j]=0; } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ for(int k=1;k<=n;k++){ box.a[i][j]=(box.a[i][j]+(x.a[i][k]*y.a[k][j])%mod)%mod; } } } return box; } node ju_pow(ll k){ node ans; for(int i=1;i<=n;i++){ ans.a[i][i]=1; } while(k){ if(k%2){ ans=qu(ans,p); } p=qu(p,p); k/=2; } return ans; } int main(){ cin>>n>>k; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%lld",&p.a[i][j]); } } pp=ju_pow(k); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ printf("%lld ",pp.a[i][j]); } cout<<endl; } }
模板快
#include<iostream> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long LL; const int N = 7; const LL mod = 2147493647; LL n, m; struct mac { LL c[N][N]; void reset() { memset(c, 0, sizeof(c)); for (int i = 0; i <= 6; i++) c[i][i] = 1; } }; mac multi(mac a, mac b) { mac ans; for (int i = 0; i <= 6; i++) for (int j = 0; j <= 6; j++) { ans.c[i][j] = 0; for (int k = 0; k <= 6; k++) { ans.c[i][j] += (a.c[i][k] * b.c[k][j]) % mod; ans.c[i][j] %= mod; } } return ans; } mac Pow(mac a, LL b) { mac ans; ans.reset(); while (b) { if (b & 1) ans = multi(ans, a); a = multi(a, a); b >>= 1; } return ans; } int main() { int t; LL n,kk,ll; mac a={ 1,2,1,0,0,0,0, 1,0,0,0,0,0,0, 0,0,1,4,6,4,1, 0,0,0,1,3,3,1, 0,0,0,0,1,2,1, 0,0,0,0,0,1,1, 0,0,0,0,0,0,1 }; cin>>t; while(t--){ cin>>n>>kk>>ll; if(n==1){ printf("%lld ",kk); } else if(n==2){ printf("%lld ",ll); } else{ mac res=Pow(a,n-2); LL ans=(ll*res.c[0][0]%mod+kk*res.c[0][1]%mod+81*res.c[0][2]%mod+27*res.c[0][3]%mod+9*res.c[0][4]%mod+3*res.c[0][5]%mod+res.c[0][6]%mod)%mod; printf("%lld ",ans%mod); } } return 0; }