版权声明:本文为博主原创文章,禁止所有形式的未经博主允许的转载行为。 https://blog.csdn.net/qq_33330876/article/details/81674195
题目大意
求 Fn ,(n<=1e9)。
解题思路
由于
的取值只有 sqrt(n) 种情况,所以分段进行矩阵快速幂转移。转移矩阵如下:
代码
我居然忘记分块除法怎么写了,生气(啪!)。
#include <bits/stdc++.h>
using namespace std;
const int maxn=int(1e5)+111, moder=int(1e9)+7;
typedef pair<int,int> pii;
inline int add(const int &a,const int &b) {return (a+b<moder)?(a+b):(a+b-moder);}
inline int mul(const int &a,const int &b) {return 1ll*a*b%moder;}
int n,P,A,B,C,D;
vector<pii> v;
struct Mat {
int a[3][3];
Mat() {
for(int i=0;i<3;++i)
for(int j=0;j<3;++j)
a[i][j]=0;
}
Mat operator * (const Mat &rhs) const {
Mat R;
for(int i=0;i<3;++i)
for(int j=0;j<3;++j) {
R.a[i][j]=0;
for(int k=0;k<3;++k)
R.a[i][j]=add(R.a[i][j],mul(a[i][k],rhs.a[k][j]));
}
return R;
}
}ori, mov;
Mat fpow(Mat a,int k) {
Mat res;
for(int i=0;i<3;++i) res.a[i][i]=1;
for(;k;k>>=1,a=a*a) if(k&1) res=res*a;
return res;
}
void work() {
scanf("%d%d%d%d%d%d",&A,&B,&C,&D,&P,&n); n-=2;
register int i,j;
for(i=0;i<3;++i)
for(j=0;j<3;++j)
ori.a[i][j]=mov.a[i][j]=0;
ori.a[0][1]=A, ori.a[0][2]=B;
mov.a[0][0]=mov.a[0][2]=mov.a[2][1]=1, mov.a[1][2]=C, mov.a[2][2]=D;
int a=3, b=0, cnt=0;
while(a<=P && n) {
b=min(P,P/(P/a)), cnt=min(n,b-a+1);
ori.a[0][0]=P/a;
ori=ori*fpow(mov,cnt);
n-=cnt;
a=b+1;
}
if(n) {
ori.a[0][0]=0;
ori=ori*fpow(mov,n);
}
printf("%d\n",ori.a[0][2]);
return;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
int T;
for(scanf("%d",&T);T;T--)
work();
return 0;
}