快速幂凭自己理解去写的代码比较繁杂:
#include<bits/stdc++.h>
using namespace std;
long long kuaisumi(long long a,long long b,long long m)
{
long long sum=1;
while(1)
{
if(b==1)return a*sum%m;
else if(b%2)
{
sum=sum*a%m;
a=a*a%m;
b/=2;
}
else
{
a=a*a%m;
b/=2;
}
}
}
int main()
{
long long a,b,m;
cin>>a>>b>>m;
long long p=kuaisumi(a,b,m)%m;
cout<<p<<endl;
}
所以后面就直接换成快速幂的板子了,观感和写法都会方便很多,有助于代码规整程度:
#include<bits/stdc++.h>
using namespace std;
int quickpow(long long a,long long b,long long m)
{
int res=1;
while(b)
{
if(b%2)res=res*a%m;
a=a*a%m;
b/=2;
}
return res;
}
int main()
{
int a,b,m;
cin>>a>>b>>m;
int p=quickpow(a,b,m)%m;
cout<<p<<endl;
}
麦森数
通过快速幂结合高精度乘法
但是早上的代码过了放到下午就过不了了,交了两遍一模一样的代码结果却报了两个错误,有点懵逼,目前还没找到原因,先附上早上AC的代码
#include<bits/stdc++.h>
using namespace std;
int la,lb;
const int N=600;
int Times(int res[],int A[])
{
int C[N];
memset(C,0,sizeof(C));
for(int i=1;i<=500;i++)
{
for(int j=1;j<=500;j++)
{
if(i+j-1>500)continue;
C[i+j-1]=C[i+j-1]+A[i]*res[j];
C[i+j]+=C[i+j-1]/10;
C[i+j-1]%=10;
}
}
for(int i=1;i<=500;i++)res[i]=C[i];
}
int quickpow(int A[],int p)
{
int res[N];
memset(res,0,sizeof(res));
res[1]=1;
while(p)
{
if(p%2)Times(res,A);
Times(A,A);
p/=2;
}
res[1]--;
int t=1;
while(res[t]<0)
{
res[t+1]--;
res[t]+=10;
t++;
}
for(int i=500;i>=1;i--)
{
cout<<res[i];
}
}
int main()
{
int p,m;
cin>>p;
int A[N];
memset(A,0,sizeof(A));
A[1]=2;
printf("%d\n",(int)(log10(2)*p+1));
quickpow(A,p);
}
矩阵快速幂也是快速幂的一种,只不过乘法部分是矩阵乘法,这里我就直接手写一段矩阵乘法的子程序就可以了
但是不知道为什么在定义Mod前面不加const导致超时,洛谷上面跑了一下要3s,加了const的话就是0.9s左右,不是很懂为什么,不过之后遇到这种全局变量不变的定义就直接加const好了,视频给的板子是重载乘号来实现的,代码更简洁。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int Mod=1e9+7,N=105;
int n,k;
void Times(int res[][105],int a[][105])
{
int c[N][N];
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int p=1;p<=n;p++)
{
c[i][j]=(c[i][j]%Mod+res[i][p]*a[p][j]%Mod)%Mod;
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)res[i][j]=c[i][j];
}
}
void quickpow(int a[][105])
{
int res[105][105];
memset(res,0,sizeof(res));
for(int i=1;i<=n;i++)res[i][i]=1;
while(k)
{
if(k%2)Times(res,a);
Times(a,a);
k/=2;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cout<<res[i][j];
cout<<" ";
}
cout<<endl;
}
}
signed main()
{
int a[105][105];
cin>>n>>k;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)cin>>a[i][j];
}
quickpow(a);
}
#include<bits/stdc++.h>
using namespace std;
const long long Mod=1e9+7,N=105;
int n;
long long k;
struct matric
{
long long c[105][105];
matric()
{
memset(c,0,sizeof c);
}
}a,res;
matric operator*(matric &x,matric &y)
{
matric t;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int p=1;p<=n;p++)
{
t.c[i][j]=(t.c[i][j]%Mod+(x.c[i][p]*y.c[p][j])%Mod)%Mod;
}
}
}
return t;
}
void quickpow(long long k)
{
for(int i=1;i<=n;i++)res.c[i][i]=1;
while(k)
{
if(k&1)res=res*a;
a=a*a;
k>>=1;
}
}
signed main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)cin>>a.c[i][j];
}
quickpow(k);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cout<<res.c[i][j]%Mod<<" ";
}
if(i!=n)cout<<endl;
}
}
裴波那契数列的第n项以前写过,但是忘了,看到用矩阵实现就想起来的,本质上就是用矩阵的方法来通过矩阵快速幂从而直接得到第N项的值,之后那个题也是通过矩阵快速幂去实现的,只是后面那题是Fn=Fn-1+Fn-3
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
//#define int long long
#define ios ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
const int N = 1e5+5;
int n, mod;
struct Matrix{
int a[3][3];
Matrix() { memset(a, 0, sizeof(a)) ;}
Matrix operator* (const Matrix &b) const{
Matrix res;
for(int i = 1; i <= 2; i++){
for(int j = 1; j <= 2; j++){
for(int k = 1; k <= 2; k++){
res.a[i][j] = (res.a[i][j] + 1ll*a[i][k] * b.a[k][j] % mod ) % mod;
}
}
}
return res;
}
}base, ans;
void init(){
base.a[1][1] = base.a[1][2] = base.a[2][1] = 1;
ans.a[1][1] = ans.a[1][2] = 1;
}
void qpow(int b){
Matrix res;
res.a[1][1] = res.a[2][2] = 1;
while(b){
if(b & 1) res = res * base;
base = base * base;
b >>= 1;
}
ans = ans * res;
cout << ans.a[1][1] << endl;
}
void solve(){
cin >> n >> mod;
init();
if(n < 3){
cout << 1 << endl;
return ;
}
qpow(n - 2);
}
signed main(){
ios; int _;
_ = 1; //cin >> _;
while(_--){
solve();
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int Mod=1e9+7;
void Times(int a[][5],int b[][5])
{
int c[5][5];
memset(c,0,sizeof(c));
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
for(int p=1;p<=3;p++)c[i][j]=(c[i][j]+a[i][p]*b[p][j]%Mod)%Mod;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)a[i][j]=c[i][j];
}
void mul(int n)
{
int a[5][5]={{},{0,0,0,1},{0,1,0,0},{0,0,1,1}},res[5][5]={{},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
while(n)
{
if(n%2)Times(res,a);
Times(a,a);
n/=2;
}
cout<<(res[1][3]+res[2][3]+res[3][3])%Mod<<endl;
}
signed main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
if(n<=3)
{
cout<<1<<endl;
continue;
}
mul(n-3);
}
}