Codevs3332 数列
来源:互联网 发布:学python看什么书 编辑:程序博客网 时间:2024/05/03 03:01
题目大意:a[1]=a[2]=a[3]=1,且a[x]=a[x-3]+a[x-1] (x>3),求a数列的第n项对1000000007(10^9+7)取余的值。
思路:显然,直接乘与开数组是无法通过该题的。于是,我们想到了矩阵乘法与快速幂。开一个数组a[4]={0,1,1,1},转移矩阵为{{0,0,1},{1,0,0},{0,1,1}},经过n-3次幂后再与a相乘,这样a[3]就是所求的答案。在实际编写程序时,可以记初始矩阵为所构造的矩阵,然后进行n-4次幂。边计算边取模即可。但是我写的递归版的快速幂无法通过,所以只好又写了非递归版。
代码如下:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const long long martix[4][4]={ {0,0,0,0}, {0,0,0,1}, {0,1,0,0}, {0,0,1,1} };const long long mod=1000000007;const long long pre[4]={0,1,1,1};struct node{ long long a[4][4];};long long t,n;node calcu(node x,node y){ node tmp; memset(tmp.a,0,sizeof(tmp.a)); for (long long i=1;i<=3;++i) for (long long j=1;j<=3;++j) { for (long long k=1;k<=3;++k) tmp.a[i][j]=(tmp.a[i][j]%mod+(long long)(x.a[i][k]*y.a[k][j]%mod))%mod; } return tmp;}node work() { node ans,cnt; memcpy(ans.a,martix,sizeof(ans.a)); memcpy(cnt.a,martix,sizeof(cnt.a)); n-=4; while(n>0) { if(n&1) { ans=calcu(ans,cnt); } n>>=1; cnt=calcu(cnt,cnt); } long long m=0; m=(ans.a[1][3]+ans.a[2][3]+ans.a[3][3])%mod; printf("%lld\n",m);}void init(){ scanf("%lld",&t); while (t--) { scanf("%lld",&n); work(); }}int main(){ freopen("seq.in","r",stdin); freopen("seq.out","w",stdout); init(); return 0;}
0 0
- Codevs3332 数列
- 【codevs3332】数列
- 【Codevs3332】数列
- 数列
- 数列
- 数列
- 数列!!!
- 数列
- 数列
- 数列
- 数列
- 数列
- 数列
- 数列
- 数列
- 数列
- 数列
- 数列
- 选村长(360笔试)
- SDWebImage加载网络图片
- Android快速开发,十个最常用的框架
- FZU 2184 还原逆序数
- A Simple Task
- Codevs3332 数列
- C++基础知识
- bcb 6.0工程平移C++ builder xe8环境
- PEM文件登录EC2时的异常的解决方式
- iOS开发:KVO和KVC
- Linux文件系统索引节点inode详解
- 可变长参数列表
- OC中字符串的方法使用(NSString、NSMutableString、NSRange)
- Dota2游戏布局