分段的时候边界用这个公式计算:ll j = P/i==0?n:min(n, P/(P/i));
#include <cstdio>
#include <cmath>
#include <cassert>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int mx = 1e5 + 5;
ll f[mx], A, B, C, D, P, n;;
ll ans , m, f1, f2;
struct node {
ll mat[5][5];
node () {memset(mat, 0, sizeof(mat));}
node operator *(const node b)
{
node tmp = node();
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
for (int k = 0; k < 3; k++)
tmp.mat[i][j] = (tmp.mat[i][j] + mat[i][k]*b.mat[k][j] % mod) % mod;
return tmp;
}
void show() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%d%c",mat[i][j], j==2?'\n':' ');
}
}
puts("");
}
};
ll pow_mod(ll f1, ll f2, ll c, ll k, ll p, ll q) {
node ans = node();
node a = node();
a.mat[0][0] = D;
a.mat[0][1] = 1;
a.mat[1][0] = C;
a.mat[2][0] = 1;
a.mat[2][2] = 1;
for (int i = 0; i < 3; i++) ans.mat[i][i] = 1;
while (k > 0) {
if (k & 1)
ans = ans * a;
a = a * a;
k /= 2;
}
//if (p == 65) ans.show();
ll sum = 0;
sum = (sum + ans.mat[0][0]*f2%mod) % mod;
sum = (sum + ans.mat[1][0]*f1%mod) % mod;
sum = (sum + ans.mat[2][0]*c%mod) % mod;
return sum;
}
ll solve() {
if (n == 1) return A;
if (n == 2) return B;
ll f1 = A, f2 = B;
for (ll i = 3; i <= n; i++) {
ll j = P/i==0?n:min(n, P/(P/i));
//printf("i = %lld j = %lld\n", i, j);
ll tmp1, tmp2, c = P/i;
if (i == j) {
tmp2 = (C*f1%mod + D*f2%mod + c) % mod;
tmp1 = f2;
}
else {
tmp1 = pow_mod(f1, f2, c, j-i, i, j);
tmp2 = pow_mod(f1, f2, c, j-i+1, i, j);
}
f1 = tmp1; f2 = tmp2;
//printf("f1 = %lld f2 = %lld\n", f1, f2);
i = j;
}
return f2;
}
int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int T;
scanf("%d", &T);
while (T--) {
scanf("%lld%lld%lld%lld%lld%lld", &A, &B, &C, &D, &P, &n);
f[1] = A; f[2] = B;
printf("%lld\n", solve());
}
return 0;
}