Let us define a sequence as below
⎧⎩⎨⎪⎪⎪⎪⎪⎪F1F2Fn===ABC⋅Fn−2+D⋅Fn−1+⌊Pn⌋{F1=AF2=BFn=C⋅Fn−2+D⋅Fn−1+⌊Pn⌋
Your job is simple, for each task, you should output FnFn module 109+7109+7.
Input
The first line has only one integer TT, indicates the number of tasks.
Then, for the next TT lines, each line consists of 66 integers, AA , BB, CC, DD, PP, nn.
1≤T≤200≤A,B,C,D≤1091≤P,n≤1091≤T≤200≤A,B,C,D≤1091≤P,n≤109
Output
36 24
Sample Input
2 3 3 2 1 3 5 3 2 2 2 1 4
Sample Output
36 24
题意:算出给定的递推式,留意到下取整对于一段连续区间的值都一样,那么分段处理即可,分段数为根号n级别,那么套矩阵快速幂就是O(sqrt(n) * log(n))。
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9+7;
struct Mat{LL mat[3][3];};
int T;
LL a,b,c,d,p,n;
Mat k;
Mat operator *(Mat a, Mat b)
{
Mat c;
for(int i=0; i<3; ++i)
for(int j=0; j<3; ++j)
{
c.mat[i][j] = 0;
for(int k=0; k<3; ++k)
{
c.mat[i][j] += a.mat[i][k]*b.mat[k][j]%mod;
c.mat[i][j] %= mod;
}
}
return c;
}
Mat operator ^(Mat a, int b)
{
Mat c;
for(int i=0; i<3; ++i)
for(int j=0; j<3; ++j)
c.mat[i][j] = (i==j);
for(;b;b>>=1)
{
if(b&1) c = c*a;
a = a*a;
}
return c;
}
void solve(int n, int x)
{
k.mat[0][2] = 1LL*x;
Mat p;
for(int i=0; i<3; ++i)
for(int j=0; j<3; ++j)
p.mat[i][j] = 0;
p.mat[0][0] = d;
p.mat[1][0] = c;
p.mat[2][0] = p.mat[0][1] = p.mat[2][2] = 1LL;
p = p^n;
k = k*p;
}
int main()
{
for(scanf("%d",&T);T;--T)
{
for(int i=0; i<3; ++i)
for(int j=0; j<3; ++j)
k.mat[i][j] = 0;
LL ans = 0;
scanf("%lld%lld%lld%lld%lld%lld",&a,&b,&c,&d,&p,&n);
if(n == 1) {printf("%lld\n",a);continue;}
else if(n == 2) {printf("%lld\n",b);continue;}
k.mat[0][0] = b;
k.mat[0][1] = a;
for(int i=3,j; i<=min(p,n); i=j+1)
{
j=p/(p/i);
j = min(j, (int)n);
solve(j-i+1, p/i);
}
if(n > max(p,2*1LL)) solve(n-max(p,2*1LL), 0);
printf("%lld\n",k.mat[0][0]);
}
return 0;
}