Recursive sequence (fast matrix power template)

Posted by Hellbringer2572 on Fri, 20 Dec 2019 16:56:49 +0100

This type of questions is suitable for large numbers, recurrence and the rule from one state to another

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 Ten 23^4. In the second case, the third number is 93 = 2*1 Ten 1*10 Ten 3^4 and the fourth number is 369 = 2 * 10 Ten 934^4.

 

 

Source

2016ACM/ICPC Shenyang station, Asia-Replay (thanks to Northeastern University)

The analysis here is reprinted. I think it is clear.

Title:

Known recurrence formula: F(n) = 2*F(n-2) + F(n-1) + n4 and F(1) = a, F(2) = b; given a n, how much is F(N) equal to?

Because N is very large, the direct recursion must time out, so we need to use the complexity of the knowledge log(n) of the matrix fast power to solve it. The key of the problem lies in how to construct the matrix. It can be seen that the recurrence formula of this problem is a nonlinear formula, so the nonlinear part should be expanded to be linear.

Note: the matrix must be n*n, so that you can multiply by yourself!!! The split of n^4 is ingenious

...

Code:

 //Remember the template, the key is to find the rule
#include "bits/stdc++.h"
#define rep(i,j,k) for(int i=j;i<=k;i++)
const int MOD = 1e5+7;
typedef long long ll;
using namespace std;
const int N =7;
ll mod = 2147493647;//Must be long long 
 
struct mat
{
	ll a[N][N];
};
 
mat mul_mat(mat &a,mat &b)
{
	mat res;
	memset(res.a,0,sizeof(res.a)); 
	rep(i,0,6)
		rep(j,0,6)
			rep(k,0,6)
			{
				res.a[i][j]=(res.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
			}//That's the position. Previously, res.a[i][j]+a.a[i][k]*b.a[k][j]%mod was used;
                         //ac can't do it all the time. We still need bracket insurance
	return res;
}
mat pow_mat(ll n,mat &a)
{
	mat res;
	memset(res.a,0,sizeof(res.a));
	for(int i=0;i<=6;i++)
	res.a[i][i]=1;
	while(n)
	{
		if(n&1) res=mul_mat(res,a);
		a=mul_mat(a,a);
		n>>=1;
	}
	return res;
}
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		int a,b,m;
		cin>>m>>a>>b;
		int c[]={a,b,16,8,4,2,1};
		if(m==1)
		cout<<a<<endl;
		else if(m==2)
		cout<<a<<endl;
		else
		{
			mat res=
			{
				0,1,0,0,0,0,0,
				2,1,1,4,6,4,1,
				0,0,1,4,6,4,1,
				0,0,0,1,3,3,1,
				0,0,0,0,1,2,1,
				0,0,0,0,0,1,1,
				0,0,0,0,0,0,1,
			};
			mat cur=pow_mat(m-2,res);
			ll sum=0;
			for(int i=0;i<=6;i++)
			{
				sum=((sum+cur.a[1][i]*c[i])%mod);
			}
			cout<<sum<<endl;
		}
	}
	
	return 0;
}