HDU5950 Recursive sequence 非線性遞推式 矩陣快速冪
題目描述:給出一個數列的第一項和第二項,計算第n項。
遞推式是 f(n)=f(n-1)+2*f(n-2)+n^4.
由於n很大,所以肯定是矩陣快速冪的題目,但是矩陣快速冪只能解決線性的問題,n^4在這個式子中是非線性的,後一項和前一項沒有什麼直接關係,所以模擬賽的時候想破頭也不會做。
這裡要做一個轉換,把n^4變成一個線性的,也就是和(n-1)^4有關係的東西,而這個辦法就是:
n^4=(n-1+1)^4=(n-1)^4+4*(n-1)^3+6*(n-1)^2+4*(n-1)^1+(n-1)^0;
這個轉換就建立了某一項和前一項的關係,矩陣的F陣列就是 f[7]={ b , a , 81 , 27 , 9 , 3 , 1 };,整體的矩陣也很好構造,程式碼裡有。
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<string.h> #include<sstream> #include<set> #include<map> #include<vector> #include<queue> #include<stack> #include<bitset> #define CLR(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; ll mod=2147493647; inline int rd(void) { int x=0; int f=1;char s=getchar(); while(s<'0'||s>'9') { if(s=='-')f=-1; s=getchar();} while(s>='0'&&s<='9') { x=x*10+s-'0';s=getchar();} x*=f;return x; } ll n,a,b; void mul(ll f[7],ll a[7][7]){ ll c[7]; CLR(c,0); for(int j=0;j<7;j++){ for(int k=0;k<7;k++){ c[j]=(c[j]+f[k]*a[k][j]%mod)%mod; } } memcpy(f,c,sizeof(c)); } void mulself(ll a[7][7]){ ll c[7][7]; CLR(c,0); for(int i=0;i<7;i++){ for(int j=0;j<7;j++){ for(int k=0;k<7;k++){ c[i][j]=(c[i][j]+a[i][k]*a[k][j]%mod)%mod; } } } memcpy(a,c,sizeof(c)); } int main(){ int T; cin>>T; while(T--){ scanf("%lld%lld%lld",&n,&a,&b); if(n==1){ printf("%lld\n",a); }else if(n==2){ printf("%lld\n",b); }else{ ll f[7]={b,a,81,27,9,3,1}; ll a[7][7]= {{1,1,0,0,0,0,0}, {2,0,0,0,0,0,0}, {1,0,1,0,0,0,0}, {0,0,4,1,0,0,0}, {0,0,6,3,1,0,0}, {0,0,4,3,2,1,0}, {0,0,1,1,1,1,1}}; n-=2; for(;n;n>>=1){ if(n&1)mul(f,a); mulself(a); } printf("%lld\n",f[0]); } } }
Recursive sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3374 Accepted Submission(s): 1485
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.