• 【矩阵快速幂】数列


    [NOIP模拟赛]数列

    【题目描述】
      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
    ",m1[1][1]%mod); 
    	}
    }
  • 相关阅读:
    Android系统架构概述
    过滤IE浏览器版本
    gearman入门使用
    MYSQL中利用select查询某字段中包含以逗号分隔的字符串的记录方法
    PHP操作Excel – PHPExcel 基本用法详解
    java中怎么判断一个字符串是否存在数组中
    为java程序制作exe
    jsonp的原理
    mysql的联合查询
    移动开发---页面头部信息
  • 原文地址:https://www.cnblogs.com/wxjor/p/7357174.html
Copyright © 2020-2023  润新知