2016ACM/ICPC亚洲区沈阳站 C Recursive sequence (矩阵快速幂)

Recursive sequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2187    Accepted Submission(s): 969


Problem Description
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 = 2*1十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.
 

Source


123

 Fn = 2 * Fn-2 + Fn-2  + n ^4 

 矩阵快速幂


n^4  =  (n-1) ^4 +  4 * (n-1) ^3 + 6 *(n-1)^2 + 4 *(n-1)^1 + 1* (n-1)^0


构造矩阵:



【代码实现】


#include <iostream>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <bits/stdc++.h>
#include <string.h>

#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;

typedef long long ll;
const int maxn=1e6+5;
const ll mod=2147493647;
const ll MOD=2147493647;
const int N=10;
const int MAXN=7;

struct Matrix{
	ll arr[N][N];
	void init()
	{
		memset(arr,0,sizeof(arr));
		for(int i=0;i<MAXN;i++)
			arr[i][i]=1;//初始化
	}
	void iinit()
	{
		memset(arr,0,sizeof(arr));
		// 矩阵初始赋值 为快速幂准备
		arr[0][0]=1;arr[0][1]=2,arr[0][2]=1,arr[0][3]=4,arr[0][4]=6,arr[0][5]=4,arr[0][6]=1;
        arr[1][0]=1;
                                arr[2][2]=1,arr[2][3]=4,arr[2][4]=6,arr[2][5]=4,arr[2][6]=1;
                                            arr[3][3]=1,arr[3][4]=3,arr[3][5]=3,arr[3][6]=1;
                                                        arr[4][4]=1,arr[4][5]=2,arr[4][6]=1;
                                                                    arr[5][5]=1,arr[5][6]=1;
                                                                    			arr[6][6]=1;
	}
}A;
Matrix mul(Matrix X,Matrix Y)// 矩阵乘法
{
	Matrix ans;
	for(int i=0;i<MAXN;i++)
		for(int j=0;j<MAXN;j++){
			ans.arr[i][j]=0;
			for(int k=0;k<MAXN;k++){
				ans.arr[i][j]=(X.arr[i][k]*Y.arr[k][j]+ans.arr[i][j])%mod;
			ans.arr[i][j]%mod;
			}
		}
	return ans;
}
Matrix Q_pow(Matrix B,ll n)// 矩阵快速幂 
{
	Matrix ans;
	ans.init();
	while(n)
	{
		if(n&1)
			ans=mul(ans,B);
		n>>=1;
		B=mul(B,B);
	}
	return ans;
}

int main()
{
	ll n,a,b;
	int t;
	cin>>t;
	while(t--)
	{
		scanf("%lld %lld %lld",&n,&a,&b);
		
		Matrix ans;
		ans.iinit();
		if(n==1)
		{
			printf("%lld\n",a%mod);
			continue;
		}
		if(n==2)
		{
			printf("%lld\n",b%mod);
			continue;
		}
		ans=Q_pow(ans,n-2);
		ll res=0;
        res+=(b*ans.arr[0][0]%mod +ans.arr[0][1]*a%mod)%mod;
        res+=(ans.arr[0][2]*16 +ans.arr[0][3]*8+ans.arr[0][4]*4+ans.arr[0][5]*2+ans.arr[0][6])%mod;
        
        printf("%lld\n",res%mod);
		
	}
}




posted @ 2017-10-14 20:13  Sizaif  阅读(230)  评论(0编辑  收藏  举报