您的位置:首页 > 其它

【矩阵快速幂】数列

2017-08-14 12:42 429 查看
[b][NOIP模拟赛]数列[/b]

【题目描述】
  a[1]=a[2]=a[3]=1
  a[x]=a[x-3]+a[x-1] (x>3)
  求a 数列的第n 项对1000000007(10^9+7)取余的值。

【输入格式】
  第一行一个整数T,表示询问个数。
  以下T 行,每行一个正整数n。

【输出格式】
  每行输出一个非负整数表示答案。

【样例输入】
3
6
8
10

【样例输出】
4
9
19

【数据范围】
  对于30%的数据 n<=100;
  对于60%的数据 n<=2*10^7;
  对于100%的数据 T<=100,n<=2*10^9;

试题分析:60%直接递推就好

     至于100%的就用矩阵快速幂。

     0 1 0   1

     0 0 1 ^ (k-2) * 1

     1 0 1   1

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
#define LL long long
LL m1[7][7];
LL m2[7][7];
LL m3[7][7];
int N;
const int mod=1000000007;

void cheng(){
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++)
m2[i][j]=m3[i][j];
}
memset(m3,0,sizeof(m3));
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
for(int k=1;k<=N;k++)
m3[i][j]+=m2[i][k]*m1[k][j]%mod,m3[i][j]%=mod;
}
}
}
void cheng2(){
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++)
m2[i][j]=m1[i][j];
}
memset(m1,0,sizeof(m1));
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
for(int k=1;k<=N;k++)
m1[i][j]+=m2[i][k]*m2[k][j]%mod,m1[i][j]%=mod;
}
}
}
void Pow(int b){
while(b){
if(b&1) cheng();
b>>=1;
cheng2();
}
return ;
}
void chengk(){
for(int a=1;a<=3;a++)
for(int b=1;b<=1;b++)
for(int c=1;c<=3;c++)
m1[a][b]+=m3[a][c]*m2[c][b]%mod,m1[a][b]%=mod;
return;
}
int main(){
int T=read();
while(T--){
int k=read(); N=3;
memset(m1,0,sizeof(m1));
memset(m3,0,sizeof(m3));
m1[1][2]=m3[1][2]=1;
m1[2][3]=m3[2][3]=1;
m1[3][1]=m3[3][1]=1;
m1[3][3]=m3[3][3]=1;
Pow(max(k-2,0));
memset(m1,0,sizeof(m1));
m2[1][1]=1,m2[2][1]=1,m2[3][1]=1;
chengk();
printf("%lld\n",m1[1][1]%mod);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: