专栏文章
11.23倍增 / st表 / 矩阵乘法
个人记录参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqyhhht
- 此快照首次捕获于
- 2025/12/04 12:48 3 个月前
- 此快照最后确认于
- 2025/12/04 12:48 3 个月前
快速幂的思想是把b拆分成的形式,每一次取它的一个二进制位,如果是1,就将乘进答案中,否则就跳过。
例如b为,则b可以被拆成;若b为,则b可以被拆成。
Code:
CPPCode:
#include<iostream>
using namespace std;
long long ksm(long long a,long long b,long long m){
long long res=1,tmp=a;
while(b){
if(b%2==1) res=res%m*tmp%m;
tmp=tmp*tmp%m;
b/=2;
}
return res;
}
int main(){
long long a,b,mod,ans;
cin>>a>>b>>mod;
ans=ksm(a,b,mod);
cout<<a<<"^"<<b<<" mod "<<mod<<"="<<ans;
return 0;
}
矩阵快速幂其实就是把快速幂中乘号对应的两个对象换成了矩阵而已,只需要专门定义一个函数(或重载乘号)来计算矩阵乘法就行了。
Code:
CPPCode:
#include<iostream>
using namespace std;
long long n,k,ans[101][101],t[101][101],mod=1e9+7;
inline void jzc(bool f){
long long fl[101][101]={};
if(f){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
fl[i][j]=(fl[i][j]%mod+t[i][k]%mod*t[k][j]%mod)%mod;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) t[i][j]=fl[i][j];
}
}else{
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
fl[i][j]=(fl[i][j]%mod+ans[i][k]%mod*t[k][j]%mod)%mod;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) ans[i][j]=fl[i][j];
}
}
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) cin>>t[i][j];
}
for(int i=1;i<=n;i++) ans[i][i]=1;
while(k){
if(k&1) jzc(0);
jzc(1);
k>>=1;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) printf("%lld ",ans[i][j]%mod);
putchar('\n');
}
return 0;
}
首先,我们已知,把它写成矩阵乘法的形式即为:
像这样推下去,我们会得到:
像这样推下去,我们会得到:
已知,这就变成了一道矩阵快速幂。
Code:
CPPCode:
#include<iostream>
using namespace std;
long long n,s,ans[3][3],t[3][3],mod=1e9+7;
inline void jzc(bool f){
long long fl[3][3]={};
if(f){
for(int k=1;k<=2;k++){
for(int i=1;i<=2;i++){
for(int j=1;j<=2;j++){
fl[i][j]=(fl[i][j]%mod+t[i][k]%mod*t[k][j]%mod)%mod;
}
}
}
for(int i=1;i<=2;i++){
for(int j=1;j<=2;j++) t[i][j]=fl[i][j];
}
}else{
for(int k=1;k<=2;k++){
for(int i=1;i<=2;i++){
for(int j=1;j<=2;j++){
fl[i][j]=(fl[i][j]%mod+ans[i][k]%mod*t[k][j]%mod)%mod;
}
}
}
for(int i=1;i<=2;i++){
for(int j=1;j<=2;j++) ans[i][j]=fl[i][j];
}
}
}
int main(){
cin>>n;
if(n<=2){
cout<<1;
return 0;
}
s=n-2;
ans[1][1]=1;
ans[1][2]=1;
t[1][1]=1;
t[1][2]=1;
t[2][1]=1;
while(s){
if(s&1) jzc(0);
jzc(1);
s>>=1;
}
cout<<ans[1][1];
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...