题意:
给出你如上递推式,让你求第
项。
思路:
由于
不是常数,我们不能直接用矩阵快速幂,根据整除分块的特点,我们分段进行矩阵快速幂即可。
构造转移矩阵
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
using namespace std;
#define ll long long
const int N = 1e5 +5;
#define LL long long
const LL mod = 1e9 + 7 ;
struct mat
{
LL m[3][3];//矩阵大小
mat() {
memset(m,0,sizeof(m));
}
mat operator * (mat &a ) {//重载 * 运算符
mat ans;
for (int i=0 ;i < 3 ;i++ ){//矩阵乘法
for (int k=0 ;k<3 ;k++) if(m[i][k]) {
for (int j=0 ;j<3 ;j++) if(a.m[k][j]) {
ans.m[i][j]=(ans.m[i][j]+m[i][k]*a.m[k][j])%mod;//取模
}
}
}
return ans;
}
};
mat mat_pow(mat a,LL b)//矩阵快速幂
{
mat ans;
for (int i=0 ;i < 3 ;i++ ) ans.m[i][i]=1;//单位阵
while(b) {
if (b&1) ans=ans*a;
b=b>>1;
a=a*a;
}
return ans;
}
int main(){
int t;
cin >> t;ll a,b,c,d,p,n;
while(t --){
cin >> a >> b >> c >> d >> p >> n;
if(n == 1) cout<<a<<endl;
else if(n == 2) cout<<b<<endl;
else {
LL mm[3][3] = {
{d,c,0},
{1,0,0},
{0,0,1},
};
mat ans ;
for(int i = 0;i < 3;++i){
for(int j = 0;j < 3;++j)
ans.m[i][j] = mm[i][j];
}
bool rt = 0;
for(ll l = 3,r;l <= n;l = r + 1){
if(p / l == 0){
mat tmp;
tmp = ans;
tmp = mat_pow(tmp,n-l+1);
rt = 1;
ll res = (tmp.m[0][0] * b % mod+ tmp.m[0][1] *a%mod+tmp.m[0][2]%mod)%mod;
cout<<res<<endl;break;
}
else{
r = min(p /(p/l),n);
mat tmp;
tmp = ans;
tmp.m[0][2] = p/l;
tmp = mat_pow(tmp,r - l + 1);
ll B = (tmp.m[0][0] * b % mod+ tmp.m[0][1] *a%mod+tmp.m[0][2]%mod)%mod;
ll A = (tmp.m[1][0] * b % mod+ tmp.m[1][1] *a%mod+tmp.m[1][2]%mod)%mod;
a = A,b = B;
}
}
if(!rt) cout<<b<<endl;
}
}
}