• Recursive sequence


    Farmer John likes to play mathematics games with his N cows. Recently, they are attracted by recursive sequences. In each turn, the
    cows would stand in a line, while John writes two positive numbers a
    and b on a blackboard. And then, the cows would say their identity
    number one by one. The first cow says the first number a and the
    second says the second number b. After that, the i-th cow says the sum
    of twice the (i-2)-th number, the (i-1)-th number, and i4. Now, you
    need to write a program to calculate the number of the N-th cow in
    order to check if John’s cows can make it right.

    Input
    The first line of input contains an integer t, the number of test cases. t test cases follow.
    Each case contains only one line with three numbers N, a and b where N,a,b < 231 as described above.
    Output
    For each test case, output the number of the N-th cow. This number might be very large, so you need to output it modulo 2147493647.
    Sample Input
    2
    3 1 2
    4 1 10
    Sample Output
    85
    369

    Hint
    In the first case, the third number is 85 = 21十2十3^4.
    In the second case, the third number is 93 = 2
    1十1*10十3^4 and the fourth number is 369 = 2 * 10 十 93 十 4^4.

    题目大意:根据题目所给方法,求出f(n);运用矩阵快速幂。

    矩阵快速幂的多种类型:f[n]=af[n-1]+bf[n-2]+c;
    f[n]=af[n-1]+bf[n-2]+n^m
    这题就用到了第二种类型。

    在这里插入图片描述

    Code:

    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const ll mod = 2147493647UL;//定义一个很大的变量时,编译器会报错,但使用UL之后就不会了
    struct node {
    	ll materix[8][8];
    };
    
    node mul(node a,node b){//矩阵乘法
    	node res;
    	memset(res.materix,0,sizeof(res.materix));
    	for(int i=1;i<=7;i++){
    		for(int j=1;j<=7;j++){
    			for(int k=1;k<=7;k++){
    				res.materix[i][j]=(res.materix[i][j]+a.materix[i][k]*b.materix[k][j]%mod)%mod;
    			}
    		}
    	}
    	return res;	
    }
    
    node ksm(node a,int b){//矩阵快速幂
    	node ans;
    	memset(ans.materix,0,sizeof(ans.materix));
    	for(int i=1;i<=7;i++) ans.materix[i][i]=1;//一定要对ans进行初始化
    	while(b){
    		if(b&1) ans=mul(ans,a);
    		a=mul(a,a);
    		b>>=1;
    	}
    	return ans;
    	
    }
    
    int main(){
    	int t;
    	cin>>t;
    	while(t--){
    		ll a;
    		ll n,b;
    		cin>>n>>a>>b;
    		node x,y;
    		x.materix[1][1]=a;x.materix[2][1]=b;x.materix[3][1]=pow(2,4);//矩阵初始化
    		x.materix[4][1]=pow(2,3);x.materix[5][1]=pow(2,2);x.materix[6][1]=2,x.materix[7][1]=1;
    		memset(y.materix,0,sizeof(y.materix));
    		y.materix[1][2]=1;y.materix[2][1]=2;y.materix[2][2]=1;y.materix[2][3]=1;y.materix[2][4]=4;//矩阵初始化
    		y.materix[2][5]=6;y.materix[2][6]=4;y.materix[2][7]=1;y.materix[3][3]=1;y.materix[3][4]=4;
    		y.materix[3][5]=6;y.materix[3][6]=4;y.materix[3][7]=1;y.materix[4][4]=1;y.materix[4][5]=3;
    		y.materix[4][6]=3;y.materix[4][7]=1;y.materix[5][5]=1;y.materix[5][6]=2;y.materix[5][7]=1;
    		y.materix[6][6]=1;y.materix[6][7]=1;y.materix[7][7]=1;
    		node ans=ksm(y,n-2);
    		ans=mul(ans,x);
    		cout<<ans.materix[2][1]%mod<<endl;
    		
    	}
    	
    	return 0;
    }
    
    
    七月在野,八月在宇,九月在户,十月蟋蟀入我床下
  • 相关阅读:
    深度排序与alpha混合 【转】
    SVN服务器配置说明 【转】
    3D空间中射线与轴向包围盒AABB的交叉检测算法 【转】
    Linux系统管理员不可不知的命令:sudo
    Linux 系统实时监控的瑞士军刀 —— Glances
    shell定期转移日志文件到云盘并定期删除云盘文件
    zabbix监控第二块网卡是否连通
    Gitlab自动触发Jenkins构建打包
    shell脚本检测网络是否畅通
    Prometheus入门
  • 原文地址:https://www.cnblogs.com/voids5/p/12695037.html
Copyright © 2020-2023  润新知