Array Challenge
There’s an array that is generated by following rule.
h0=2,h1=3,h2=6,hn=4hn−1+17hn−2−12hn−3−16
And let us define two arrays
bnandan
as below.
iibn=n+1hn+9hn+1hn−1+9hn2+27hnhn−1−18hn+1−126hn−81hn−1+192(n>0)
an=bn+4n
Now, you have to print ⌊√(an)⌋
, n>1.
Your answer could be very large so print the answer modular 1000000007.
Input
The first line of input contains T (1 <= T <= 1000) , the number of test cases.
Each test case contains one integer n (1 < n <=
1015)
in one line.
Output
For each test case print ⌊√(a_n )⌋ modular 1000000007.
Sample Input
3
4
7
9
Sample Output
1255
324725
13185773
題意很簡單了,就是求 { sqrt(a[n]) },但是公式怎麼推出來就很難了,官方題解如此:
表示看半天雖然推出了但是很複雜,就搜了一下別人的博客,發現一個玄學的解答,具體思路就是打個表,然後瞎貓碰死耗子,直接假設 sqrt(a(n)) 滿足Hn 的遞推式,結果還真是的......(ORZ
設 要求的爲 Fn, Fn=4Fn-1 + 17Fn-2 -12Fn-3;
F2=31;F3=197; F4=1225;F5=7997;
接下來就是矩陣快速冪了。
Fn 4 1 0 Fn
Fn-1 17 0 1 Fn-1
Fn-2 -12 0 0 Fn-2
#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include <bits/stdc++.h>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#define maxn 10010
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define ll long long
using namespace std;
struct Node
{
ll a[5][5];
Node()
{
memset(a,0,sizeof a);
}
};
Node Mul(Node A,Node B)
{
Node C;
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
for(int k=1;k<=3;k++)
C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j]+MOD)%MOD;
}
}
return C;
}
Node Pow(Node A,ll p)
{
Node B;
B.a[1][1]=B.a[2][2]=B.a[3][3]=1;
while(p)
{
if(p&1) B=Mul(B,A);
A=Mul(A,A);
p>>=1;
}
return B;
}
int main()
{
ll n,T;
scanf("%lld",&T);
while(T--)
{
scanf("%lld",&n);
if(n == 2) puts("31");
else if(n == 3) puts("197");
else if(n == 4) puts("1255");
else if(n == 5) puts("7997");
else
{
Node A;
memset(A.a,0,sizeof (A.a));
A.a[1][1]=4,A.a[1][2]=17,A.a[1][3]=-12;
A.a[2][1]=1,A.a[3][2]=1;
Node C=Pow(A,n-4);
ll ans=(C.a[1][1]*1255%MOD+C.a[1][2]*197%MOD+C.a[1][3]*31%MOD+MOD)%MOD;
printf("%lld\n",ans);
}
}
return 0;
}