Sequence
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2573 Accepted Submission(s): 1004
Problem Description
Let us define a sequence as below
Your job is simple, for each task, you should output Fn module 109+7.
Input
The first line has only one integer T, indicates the number of tasks.
Then, for the next T lines, each line consists of 6 integers, A , B, C, D, P, n.
1≤T≤200≤A,B,C,D≤1091≤P,n≤109
Sample Input
2
3 3 2 1 3 5
3 2 2 2 1 4
Sample Output
36
24
from:https://blog.csdn.net/weixin_39453270/article/details/81661394
#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int maxn = 1e9 + 7;
long long a,b,c,d,p,n;
struct Marix {
long long mo[3][3];
Marix() {
memset(mo,0,sizeof(mo));
}
};
Marix mul(Marix a,Marix b) {
Marix c;
for(int i = 0;i < 3;i++) {
for(int j = 0;j < 3;j++) {
for(int k = 0;k < 3;k++) {
c.mo[i][j] = (c.mo[i][j]+a.mo[i][k]*b.mo[k][j])%mod;
}
}
}
return c;
}
Marix powmod(Marix a,int n) {///矩阵快速幂模板
Marix tmp;
for(int i = 0;i < 3;i++) {
tmp.mo[i][i] = 1;
}
while(n) {
if(n&1) tmp = mul(tmp,a);
n >>= 1;
a = mul(a,a);
}
return tmp;
}
int main() {
int T;
scanf("%d",&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;
}
Marix m;
m.mo[0][0] = d,
m.mo[0][1] = c,
m.mo[1][0] = 1,
m.mo[2][2] = 1;
bool vis = 0;
for(int i = 3;i <= n;) {
if(p/i == 0) {///倘若当前项大于p了,则直接用矩阵快速幂求解剩下的项
Marix tmp;
tmp = m;
tmp = powmod(tmp,n-i+1);
long long res = (tmp.mo[0][0]*b +tmp.mo[0][1]*a +tmp.mo[0][2])%mod;
printf("%lld\n",res);
vis = 1;
break;
}///否则,不断的分段求解矩阵的值,并将矩阵的值进行修改
long long j = min(n,p/(p/i));
Marix tmp;
tmp = m;
tmp.mo[0][2] = p/i;
tmp = powmod(tmp,j-i+1);
long long A = (tmp.mo[1][0]*b + tmp.mo[1][1]*a + tmp.mo[1][2]) % mod;
long long B = (tmp.mo[0][0]*b + tmp.mo[0][1]*a + tmp.mo[0][2]) % mod;
a = A,b = B;
i = j+1;
}
if(!vis) printf("%lld\n",b);
}
return 0;
}