题目大意
求 Fn ,(n<=1e9)。
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪F1=AF2=BFn=Fn−2∗C+Fn−1∗D+⌊Pn⌋
{
F
1
=
A
F
2
=
B
F
n
=
F
n
−
2
∗
C
+
F
n
−
1
∗
D
+
⌊
P
n
⌋
解题思路
由于
⌊Pn⌋
⌊
P
n
⌋
的取值只有 sqrt(n) 种情况,所以分段进行矩阵快速幂转移。转移矩阵如下:
lhs=⎡⎣⎢⌊Pn⌋00Fn−200Fn−100⎤⎦⎥
l
h
s
=
[
⌊
P
n
⌋
F
n
−
2
F
n
−
1
0
0
0
0
0
0
]
rhs=⎡⎣⎢1000011CD⎤⎦⎥P/⌊Pn⌋
r
h
s
=
[
1
0
1
0
0
C
0
1
D
]
P
/
⌊
P
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;
}