题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6395
题目大意:
求F(n)%1e9+7
在构造系数矩阵的时候,int(p/n)是变化的,但是可以分块求和。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int mod=1e9+7;
struct mat
{
LL m[3][3];
};
mat msub(mat a, mat b, int n)
{
mat ret;
memset(&ret,0,sizeof(ret));
for(int i=0;i<n;i++)
for(int k=0;k<n;k++)
{
if(a.m[i][k]==0){
continue;
}
for(int j=0;j<n;j++){
ret.m[i][j]=(a.m[i][k]*b.m[k][j]%mod+ret.m[i][j])%mod;
}
}
return ret;
}
void unit(mat &a, int n){
for(int i=0 ;i<n; i++){
a.m[i][i]=1;
}
}
mat qpow(mat a,LL x, int n)//快速幂
{
mat ans;
memset(&ans, 0, sizeof(ans));
unit(ans, n);//初始化
while(x){
if(x&1) ans=msub(ans,a, n);
a=msub(a,a, n);
x>>=1;
}
return ans;
}
int main()
{
int t;
scanf("%d", &t);
while(t--){
LL a, b, c, d, p, n;
scanf("%lld%lld%lld%lld%lld%lld", &a, &b, &c, &d, &p, &n);
if(n==1){
printf("%lld\n", a);
continue;
}
if(n==2){
printf("%lld\n", b);
continue;
}
mat A;
A.m[0][0]=d, A.m[0][1]=c, A.m[0][2]=1;
A.m[1][0]=1, A.m[1][1]=0, A.m[1][2]=0;
A.m[2][0]=0, A.m[2][1]=0, A.m[2][2]=1;
for(int i=3; i<=n; i++){
if(p/i==0){//特判
mat t=A;
t.m[0][2]=0;
t=qpow(t, (LL)n-i+1, 3);
b=(t.m[0][0]*b%mod+t.m[0][1]*a%mod+t.m[0][2]%mod)%mod;
printf("%lld\n", b);
break;
}
else{
LL k=min(p/(p/i), (LL)n);
mat t=A;
t.m[0][2]=p/i;
t=qpow(t, k-i+1, 3);
LL s=(t.m[0][0]*b%mod+t.m[0][1]*a%mod+t.m[0][2]%mod)%mod;
a=(t.m[1][0]*b%mod+t.m[1][1]*a%mod+t.m[1][2]%mod)%mod;
b=s;
i=k;
if(k==n){
printf("%lld\n", b);
break;
}
}
}
}
return 0;
}