hdu4291 A Short problem - 矩陣快速冪 + 迴圈節
阿新 • • 發佈:2020-10-16
給出一個廣義斐波那契數列,求套娃後的值
這不是傻逼題嗎?來幾個迴圈節就行了
暴力求迴圈節
#include<cstdio> #define ll long long const ll MOD = 1e9 + 7; int main() { ll a, b; // f[n] = (bf[n - 1] + af[n - 2]) % mod; a = 1; b = 3; for(ll i = 1; ; i++) { if(a == 0 && b == 1){ printf("%lld\n", i); break; } ll c = (3 * b + a) % MOD; a = b, b = c; } return 0; }
求出
1e9 + 7 的迴圈節 222222224
222222224 的迴圈節 183120
也就是說,最裡面那層的mod是183120,第二層是222222224,第三層是1e9+7
#include <iostream> #include <cstdio> #include <cstring> #define ll long long using namespace std; const int N = 2; struct Matrix{ int n, m; ll a[N][N]; Matrix(int n = 0, int m = 0):n(n),m(m){memset(a, 0, sizeof(a));} }; Matrix mul(Matrix a, Matrix b, ll mod) { Matrix ans(a.n, b.m); for(int i = 0; i < a.n; i++) { for(int j = 0; j < b.m; j++) { for(int k = 0; k < a.m; k++) { ans.a[i][j] = (ans.a[i][j] + a.a[i][k] * b.a[k][j] % mod) % mod; } } } return ans; } Matrix ksm(Matrix a, ll b, ll mod){ Matrix ans(a.n, a.m); for(int i = 0; i < max(a.n, a.m); i++) ans.a[i][i] = 1; while(b){ if(b & 1) ans = mul(ans, a, mod); a = mul(a, a, mod); b >>= 1; } return ans; } ll f(ll n, ll mod){ if(n == 0) return 0 % mod; if(n == 1) return 1 % mod; if(n == 2) return 3 % mod; Matrix base(2, 2); Matrix ans(2, 1); base.a[0][0] = 3, base.a[0][1] = 1; base.a[1][0] = 1, base.a[1][1] = 0; base = ksm(base, n - 2, mod); ans.a[0][0] = 3, ans.a[1][0] = 1; ans = mul(base, ans, mod); return ans.a[0][0]; } int main(){ ll n; while(~scanf("%lld", &n)) { ll ans = f(n, 183120); ans = f(ans, 222222224); ans = f(ans, 1e9 + 7); printf("%lld\n", ans); } return 0; }