版权声明:岂曰无衣,与子同袍 https://blog.csdn.net/sizaif/article/details/81700345
Let us define a sequence as below
求 Fn (mod 1e9+7)
[思路]
如果没有 [P/N] 的话, 直接上快速幂就可以了,但是 有[P/N] 是变化的不是常数,
如果能转化成常数运算, 就非常简单了,
我们可以发现, [P/N] 在 某一段内 值是固定的, 所以就可以 分段 快速幂, 例如
P = 10; 10/4 ,10/5 都是2, 10/6-10/10 都是1 . 就可 找到 右端点, 然后进行快速幂...
构造矩阵:
Fn: D C P/i Fn-1
Fn-1: 1 0 0 Fn-2
P/i: 0 0 1 P/i-1
[代码]
#include <iostream>
#include <bits/stdc++.h>
#define rep(i,a,n) for(int i =a;i<=n;i++)
#define per(i,a,n) for(int i =n;i>=a;i--)
typedef long long ll;
const int maxn = 1e5+10;
const int mod =1e9+7;
const int MAXN = 3;
const int N = 5;
using namespace std;
ll A,B,C,D,P,n;
ll f[5];
struct Matrix{
ll arr[N][N];
void init()
{
memset(arr,0,sizeof(arr));
for(int i = 0;i < MAXN;i++)
arr[i][i]=1;
}
void iinit()
{
memset(arr,0,sizeof(arr));
arr[0][0] = D;arr[0][1] = C;
arr[2][2] = 1;arr[1][0] = 1;
}
};
Matrix mul(Matrix X,Matrix Y)
{
Matrix ans;
for(int i = 0;i<MAXN;i++)
for(int j=0;j<MAXN;j++){
ans.arr[i][j]=0;
for(int k =0;k<MAXN;k++){
ans.arr[i][j] += X.arr[i][k]*Y.arr[k][j];
ans.arr[i][j]%=mod;
}
}
return ans;
}
Matrix Q_pow(Matrix B,ll n)
{
Matrix ans;
ans.init();
while(n)
{
if(n&1)
{
ans = mul(ans,B);
}
B = mul(B,B);
n>>=1;
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d %d %d %d %d",&A,&B,&C,&D,&P,&n);
Matrix res;
res.iinit();
if(n<=2)
{
if(n==1)
{
printf("%d\n",A%mod);
}
else
printf("%d\n",B%mod);
continue;
}
else
{
f[1] = A,f[2] = B;
ll f1 = f[2], f2 = f[1];
for(int i = 3,gx; i<= n; i = gx+1)
{
gx = P/i ? min(P/(P/i),n):n;
res.arr[0][2] = P/i;
Matrix Ans = Q_pow(res,gx-i+1);
f[3] = ( f1*Ans.arr[0][0]%mod + f2*Ans.arr[0][1]%mod + Ans.arr[0][2]%mod )%mod;
f[4] = ( f1*Ans.arr[1][0]%mod + f2*Ans.arr[1][1]%mod + Ans.arr[1][2]%mod )%mod;
f1 = f[3];
f2 = f[4];
}
printf("%d\n",f1);
}
}
return 0;
}