This problem is not just a simple Fibonacci sequence matrix fast exponentiation; there is also a piecewise idea (number theory is also used here): To
solve this problem, I think we should first make the matrix fast exponentiation clear. OK, in fact, the fast power of matrix is the same as the fast power of exponent we usually write (analogous thinking);
first of all,
let ’s talk about the simplest matrix fast power: we can use structure knowledge or class knowledge to write;
here is the structure Body version (solving the simplest Fibonacci sequence calculation):
Then:
the calculation (the value of the nth term) Fibonacci sequence is very easy (here is the Mod used, otherwise it will cross the boundary):
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define Mod 100000007
typedef long long ll;
#define N 2//这里表示2*2的矩阵//如果是3*3的 则可以令为N 3
struct Mu{
ll a[N][N];
Mu(){
memset(a,0,sizeof(a));
}
};
Mu Multiply(Mu t1,Mu t2){//求两个矩阵相乘
Mu res;
for(ll i=0;i<N;i++){
for(ll j=0;j<N;j++){
for(ll k=0;k<N;k++)
{
res.a[i][j]=(res.a[i][j]+t1.a[i][k]*t2.a[k][j])%Mod;
}
}
}
return res;
}
Mu QP(Mu x,ll n)//矩阵快速幂 返回结果对象
{
Mu res;
res.a[0][0]=res.a[1][1]=res.a[2][2]=1;//单位矩阵
while(n){
if(n&1){
res=Multiply(res,x);
}
x=Multiply(x,x);
n>>=1;
}
return res;
}
Mu ans;
ll n,F1=1,F2=1;
void init(){
//初始化矩阵
//比如斐波那契数列
ans.a[0][0]=ans.a[0][1]=ans.a[1][0]=1;
}
void Ans(){
ans=QP(ans,n-2);//算ans^n
cout<<(ans.a[0][0]*F1+ans.a[0][1]*F2)%Mod<<endl;
}
int main(){
cin>>n;
if(n==1) return cout<<F1<<endl,0;
else if(n==2) return cout<<F2<<endl,0;
init();
Ans();
return 0;
}
Is it very powerful, hehe; but it is far from enough to solve this problem; the
first point of this problem is that the recurrence formula is not easy to find, and the second point is that the segmentation problem is a difficult point (because the normal branch timeout), solve this The AC problem can be solved by two points; just
look at the code (mainly because the parameters passed to the custom class are different from those in Java, I can distinguish it very clearly now!! Hehe);
recurrence formula:
So because of matrix multiplication The law of associativity is counted from the left;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define Mod 1000000007
struct Mu{
ll a[3][3];//就是这里我WA了很多次,没有写ll结果自己Debug了半天 我还以为自己把快速幂写错了,太无语了
Mu(){//构造函数
memset(a,0,sizeof(a));
}
};
Mu mu(Mu t1,Mu t2){
Mu res;
for(ll i=0;i<3;i++){
for(ll j=0;j<3;j++){
for(ll k=0;k<3;k++){
res.a[i][j]=(res.a[i][j]+t1.a[i][k]*t2.a[k][j])%Mod;
}
}
}
return res;
}
Mu QP(Mu x,int n){
Mu res;
res.a[0][0]=res.a[1][1]=res.a[2][2]=1;
while(n){
if(n&1){
res=mu(res,x);
}
x=mu(x,x);
n>>=1;
}
return res;
}
//int Period(int P,int i){
// int j;
//
// for(j=i;(P/i)==(P/j);j++);
// return j;
//}
int main(){
ll T,A,B,C,D,P,n;
scanf("%lld",&T);
while(T--){
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;}
ll j;
Mu s,ans;
for(int i=3;i<=n;i=j+1){
//memset(s.a,0,sizeof(s.a));//因为每次都需要置为0
s.a[0][0]=D;s.a[0][1]=C;s.a[0][2]=P/i;
s.a[1][0]=1;
s.a[2][2]=1;
//算阶段幂
if(i>P){//这里是算最后一次
ans=QP(s,n-i+1);
B=(ans.a[0][0]*B%Mod+ans.a[0][1]*A%Mod+ans.a[0][2])%Mod;
break;
}
j=min(n,P/(P/i));//这里必须要比最小值,用如果大于了n就不成立了
ans=QP(s,j-i+1);
ll t1=(ans.a[0][0]*B+ans.a[0][1]*A+ans.a[0][2])%Mod;//这里就是为什么需要更新A,B,因为由上面图的分析可以知道
ll t2=(ans.a[1][0]*B+ans.a[1][1]*A+ans.a[1][2])%Mod;
B=t1;A=t2;//因为这里的矩阵是倒起来算的,所以需要每次更新A,B
}
printf("%lld\n",B);//最后输出B
}
return 0;
}