我是直接爆1~1e5,后面的分段矩阵快速幂,和我做法类似的可以拿我的代码去对拍
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const ll sz = 1e5;
ll A, B, C, D, P, n, F[sz+10];
struct Matrix {
ll a[5][5];
Matrix operator * (const Matrix &t) {
Matrix ans;
for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) ans.a[i][j] = 0;
for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) for (int k = 0; k < 3; k++) {
ans.a[i][j] = (ans.a[i][j] + a[i][k] * t.a[k][j]) % mod;
}
return ans;
}
}matrix, ans;
void init() {
F[1] = A, F[2] = B;
for (int i = 3; i <= sz; i++) F[i] = (C*F[i-2]%mod + D*F[i-1]%mod + P / i)%mod;
matrix.a[0][0] = D, matrix.a[0][1] = C, matrix.a[0][2] = 1;
matrix.a[1][0] = 1, matrix.a[1][1] = 0, matrix.a[1][2] = 0;
matrix.a[2][0] = 0, matrix.a[2][1] = 0, matrix.a[2][2] = 1;
}
void mpow(int x) {
if (x == 0) return;
ans.a[0][0] = 1, ans.a[0][1] = 0, ans.a[0][2] = 0;
ans.a[1][0] = 0, ans.a[1][1] = 1, ans.a[1][2] = 0;
ans.a[2][1] = 0, ans.a[2][1] = 0, ans.a[2][2] = 1;
Matrix m = matrix;
while (x) {
if (x & 1) ans = ans * m;
m = m * m;
x >>= 1;
}
}
void solve() {
scanf("%lld%lld%lld%lld%lld%lld", &A, &B, &C, &D, &P, &n);
init();
if (n <= sz) {
printf("%lld\n", F[n]);
return;
}
ll a = F[sz], b = F[sz-1], c = P/(sz+1), l, r, prea, preb;
while (c) {
l = max(sz, P/(c+1)), r = min(n, P/c);
mpow(r - l);
prea = a, preb = b;
a = (ans.a[0][0]*prea%mod+ans.a[0][1]*preb%mod+ans.a[0][2]*c%mod)%mod;
b = (ans.a[1][0]*prea%mod+ans.a[1][1]*preb%mod+ans.a[1][2]*c%mod)%mod;
if (r == n) break;
c--;
}
if (c == 0) {
l = max(sz, P/1), r = n;
mpow(r - l);
prea = a, preb = b;
a = (ans.a[0][0]*prea%mod+ans.a[0][1]*preb%mod+ans.a[0][2]*c%mod)%mod;
b = (ans.a[1][0]*prea%mod+ans.a[1][1]*preb%mod+ans.a[1][2]*c%mod)%mod;
}
printf("%lld\n", a);
}
int main() {
int T;
scanf("%d", &T);
while (T--) solve();
}