PS:矩阵快速幂写疯了,没想到快速幂写着这么爽,哈哈哈哈哈哈哈~~
讲解还没来得及整理,有时间补上。
1.超超超简单斐波那契
题目链接
递归写法
class Solution {
public:
int Fibonacci(int n) {
if(n==0)return 0;
if(n==1||n==2)return 1;
return Fibonacci(n-1)+Fibonacci(n-2);
}
};
迭代写法
class Solution {
public:
int Fibonacci(int n) {
int a[40];
a[0]=0;
a[1]=a[2]=1;
for (int i = 3; i <= n; i ++ )
a[i]=a[i-1]+a[i-2];
return a[n];
}
};
2.简单的斐波那契
范围在10^6以内,用动态数组存储
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
const int mod=1e9+7;
LL f[2]={0,1};
int main()
{
int n;
cin>>n;
for(int i=2;i<=n;i++)
{
f[i&1]=(f[i-1&1]+f[i&1])%mod;
}
if(n&1)cout<<f[1]<<endl;
else cout<<f[0]<<endl;
}
3.矩阵快速幂的斐波那契
题目链接
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int mod = 10000;
int a[2][2];
void matrix_mul(int a[][2])
{
int temp[2][2]={0};
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
temp[i][j]=(temp[i][j]%mod+(LL)a[i][k]*a[k][j])%mod;
memcpy(a,temp,sizeof temp);
}
void mul(int a[],int b[][2])
{
int temp[2]={0};
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
temp[i]=(temp[i]+(LL)a[j]*b[j][i])%mod;
}
}
memcpy(a,temp,sizeof temp);
}
int main()
{
int n;
while(cin>>n,n>=0)
{
int a[2][2]={
{1,1},
{1,0}
};
int f[2]={0,1};
while (n){
if(n&1)mul(f,a);
matrix_mul(a);
n>>=1;
}
cout<<f[0]<<endl;
}
}
4.矩阵快速幂斐波那契前n项和
题目链接
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long LL;
int n,m;
void mul(int a[],int b[][3]){
int temp[3]={0};
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
temp[i]=(temp[i]+(LL)a[j]*b[j][i])%m;
memcpy(a,temp,sizeof temp);
}
void mul(int a[][3]){
int temp[3][3]={0};
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
temp[i][j]=(temp[i][j]+(LL)a[i][k]*a[k][j])%m;
memcpy(a,temp,sizeof temp);
}
int main()
{
cin>>n>>m;
int f1[3]={1,1,1};
int a[3][3]={
{0,1,0},
{1,1,1},
{0,0,1}
};
n--;
while(n){
if(n&1)mul(f1,a);
mul(a);
n>>=1;
}
cout<<f1[2]<<endl;
return 0;
}
5.佳佳的斐波那契
题目链接
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 4;
int n,m;
void mul(int c[][4],int a[][4],int b[][4]){
static int t[4][4];
memset(t, 0, sizeof t);
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
t[i][j]=(t[i][j]+(LL)a[i][k]*b[k][j])%m;
memcpy(c,t,sizeof t);
}
int main()
{
cin>>n>>m;
int f1[4][4]={1,1,1,0};
int a[4][4]={
{0,1,0,0},
{1,1,1,0},
{0,0,1,1},
{0,0,0,1},
};
int k=n-1;
while(k){
if(k&1)mul(f1,f1,a);
mul(a,a,a);
k>>=1;
}
cout<<(((LL)n*f1[0][2]-f1[0][3])%m+m)%m<<endl;
}
6.矩阵加速
题目链接
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
const int mod = 1e9+7;
void mul_m(LL f[],LL a[][3])
{
LL tmp[3]={0};
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
tmp[i]=(tmp[i]+(LL)f[j]*a[j][i])%mod;
memcpy(f,tmp,sizeof tmp);
}
void mul(LL a[][3])
{
LL tmp[3][3]={0};
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
tmp[i][j]=(tmp[i][j]+(LL)a[i][k]*a[k][j])%mod;
memcpy(a,tmp,sizeof tmp);
}
int main()
{
int m;
cin>>m;
while(m--)
{
LL n;
cin>>n;
LL f[3]={0,1,1};
LL a[3][3]={
{0,0,1},
{1,0,0},
{0,1,1}
};
while(n){
if(n&1)mul_m(f,a);
mul(a);
n>>=1;
}
cout<<f[0]<<endl;
}
}
7. Hdu5171 小奇的集合
不知道为啥在hdu代码过不了,但在下面链接里可以过,呜呜呜呜~~
题目链接
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
const int mod = 10000007;
void mul_m(LL f[],LL a[][3])
{
LL tmp[3]={0};
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
tmp[i]=(tmp[i]+(LL)f[j]*a[j][i])%mod;
memcpy(f,tmp,sizeof tmp);
}
void mul(LL a[][3])
{
LL tmp[3][3]={0};
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
tmp[i][j]=(tmp[i][j]+(LL)a[i][k]*a[k][j])%mod;
memcpy(a,tmp,sizeof tmp);
}
int main()
{
LL n,k,x,res=0;
cin>>n>>k;
LL maxv1=-1e6,maxv2=-1e6;
while(n--)
{
cin>>x;
res=(res+x)%mod;
if(x>maxv1)
{
maxv2=maxv1;
maxv1=x;
}
else if(x>maxv2)maxv2=x;
}
LL f[3];
if(maxv1<=0)
{
res+=(maxv1+maxv2)*k;
res%=mod;
cout<<res<<endl;
return 0;
}
while(maxv2<0&&k)maxv2=(maxv2+maxv1)%mod,res=(res+maxv2)%mod,k--;
f[0]=maxv2;
f[1]=maxv1;
res=(res-maxv1+mod)%mod;
f[2]=res%mod;
LL a[3][3]={
{0,1,0},
{1,1,1},
{0,0,1}
};
while(k)
{
if(k&1)mul_m(f,a);
mul(a);
k>>=1;
}
cout<<((LL)(f[1]+f[2])%mod)<<endl;
}