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.
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); } }
岂曰无衣?与子同袍。王于兴师,修我戈矛。与子同仇!
岂曰无衣?与子同泽。王于兴师,修我矛戟。与子偕作!
岂曰无衣?与子同裳。王于兴师,修我甲兵。与子偕行!