HDU 6395 Sequence 【矩陣快速冪】【分割槽】
阿新 • • 發佈:2019-02-04
Sequence
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1900 Accepted Submission(s): 729
Problem Description
Let us define a sequence as below
⎧⎩⎨⎪⎪⎪⎪⎪⎪F1F2Fn===ABC⋅Fn−2+D⋅Fn−1+⌊Pn⌋
Your job is simple, for each task, you should output Fn module 109+7.
Input
The first line has only one integer T, indicates the number of tasks.
Then, for the next T lines, each line consists of 6 integers, A , B, C, D, P, n.
1≤T≤200≤A,B,C,D≤1091≤P,n≤109
Sample Input
2 3 3 2 1 3 5 3 2 2 2 1 4
Sample Output
36 24
#include<bits/stdc++.h> using namespace std; #define ll long long const int MOD = 1e9 + 7; struct mat{ ll m[3][3]; mat(){ memset(m, 0, sizeof m); } friend mat operator * (mat a, mat b){ mat c; for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++){ ll t = 0; for(int k = 0; k < 3; k++) t += a.m[i][k] * b.m[k][j] % MOD; c.m[i][j] = t % MOD; } return c; } } E; mat POW(mat a, ll b){ mat c = E; while(b){ if(b & 1) c = c * a; a = a * a; b >>= 1; } return c; } int main(){ int N; E.m[0][0] = E.m[1][1] = E.m[2][2] = 1; for(scanf("%d", &N); N; N--){ ll a, b, c, d, p, n; cin >> a >> b >> c >> d >> p >> n; if(n == 1){ cout << a << endl; continue; } mat f; f.m[0][0] = d, f.m[0][1] = c, f.m[1][0] = 1, f.m[2][2] = 1; int flag = 0; for(int i = 3; i <= n;){ if(p / i == 0){ mat w = f; w = POW(w, n - i + 1); ll ans = w.m[0][0] * b % MOD + w.m[0][1] * a % MOD + w.m[0][2] % MOD; ans %= MOD; cout << ans << endl; flag = 1; break; } int j = min(n, p / (p / i)); mat w = f; w.m[0][2] = p / i; w = POW(w, j - i + 1); ll x = (w.m[1][0] * b % MOD + w.m[1][1] * a % MOD + w.m[1][2]) % MOD; ll y = (w.m[0][0] * b % MOD + w.m[0][1] * a % MOD + w.m[0][2]) % MOD; a = x, b = y; i = j + 1; } if(!flag) cout << b << endl; } return 0; }