https://www.nowcoder.com/acm/contest/105/G
题意 :这是一个加强版的斐波那契数列。
给定递推式求F(n)的值(n<1e18),由于这个值可能太大,请对1e9+7取模。
题解:线性代数题。矩阵快速幂
仿照斐波那契的快速幂模板。
算出F(i)与F(i+1)之间相差的的系数矩阵。
$egin{pmatrix}
1 & 1 & 1 & 1 & 1 & 1\
1 & 0 & 0 & 0 & 0 & 0\
0 & 0 & 1 & 3 & 3 & 1\
0 & 0 & 0 & 1 & 2 & 1\
0 & 0 & 0 & 0 & 1 & 1\
0 & 0 & 0 & 0 & 0 & 1
end{pmatrix}egin{pmatrix}
F_{i-1}\
F_{i-2}\
i^{3}\
i^{2}\
i\
1
end{pmatrix} =egin{pmatrix}
F_{i-1} +F_{i-2} +i^{3} +i^{2} +i+1\
F_{i-1}\
i^{3} +3i^{2} +3i+1\
i^{2} +2i+1\
i+1\
1
end{pmatrix}$
(好像看的人挺多的,贴一发公式)
然后对系数矩阵快速幂,直接用模板。
#define _CRT_SECURE_NO_WARNINGS #include<cstring> #include<cctype> #include<cstdlib> #include<cmath> #include<cstdio> #include<string> #include<stack> #include<ctime> #include<list> #include<set> #include<map> #include<queue> #include<vector> #include<sstream> #include<iostream> #include<functional> #include<algorithm> #include<memory.h> //#define INF 0x3f3f3f3f #define eps 1e-6 #define pi acos(-1.0) #define e exp(1.0) #define rep(i,t,n) for(int i =(t);i<=(n);++i) #define per(i,n,t) for(int i =(n);i>=(t);--i) #define mp make_pair #define pb push_back #define mmm(a,b) memset(a,b,sizeof(a)) //std::ios::sync_with_stdio(false); using namespace std; typedef long long ll; typedef unsigned long long ull; void smain(); #define ONLINE_JUDGE int main() { ios::sync_with_stdio(false); #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); long _begin_time = clock(); #endif smain(); #ifndef ONLINE_JUDGE long _end_time = clock(); printf("time = %ld ms.", _end_time - _begin_time); #endif return 0; } const int maxn = 4e5 + 100; const ll mod = 1e9 + 7; const ll INF = (100000)*(200000ll) + 1000; ll n, m; struct matrix { ll ma[8][8]; void clear() { mmm(ma, 0); rep(i, 1, 6)ma[i][i] = 1; } void print() { rep(i, 1, 6) { rep(j, 1, 6) { cout << ma[i][j] << ' '; }cout << endl; } } matrix mul(matrix a) { matrix ans; mmm(ans.ma, 0); rep(i,1,6) rep(j,1,6) rep(k, 1, 6) { ans.ma[i][j] += ma[i][k] * a.ma[k][j]; ans.ma[i][j] %= mod; } return ans; } matrix mul(ll a[][8]) { matrix ans; mmm(ans.ma, 0); rep(i, 1, 6) rep(j, 1, 6) rep(k, 1, 6) { ans.ma[i][j] = (ans.ma[i][j] +ma[i][k] * a[k][j])%mod; //ans.ma[i][j] %= mod; } return ans; } matrix quick(ll n) { matrix ans,a=*this; ans.clear(); while (n) { if (n& 1) { ans=ans.mul(a); } n >>= 1; a=a.mul(a); } return ans; } }; void up(ll &ans, ll t) { ans =(ans+t)%mod; } void Run() { } void smain() { ll res[8][8]; mmm(res,0); rep(i, 1, 6) res[1][i] = 1; res[2][1] = 1; res[3][3] = 1; res[3][4] = res[3][5] = 3; res[3][6] = 1; res[4][4] =res[4][6]= 1; res[4][5] = 2; res[5][5] = res[5][6] =res[6][6]= 1; int t; cin >> t; while (t--) { cin >> n; matrix ans; ans.clear(); ans=ans.mul(res); //ans.print(); ans = ans.quick(n-1); //ans.print(); //ans.ma = res; ll x=0; up(x, ans.ma[1][1]); //up(x, ans.ma[1][2]); up(x, ans.ma[1][3] * 8%mod); up(x, ans.ma[1][4] * 4%mod); up(x, ans.ma[1][5] * 2%mod); up(x, ans.ma[1][6]); cout << x%mod << endl; } }