杭电多校第七场-J-Sequence
题目描述
Let us define a sequence as below
Your job is simple, for each task, you should output Fn module 109+7.
Your job is simple, for each task, you should output Fn module 109+7.
输入
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≤20 0≤A,B,C,D≤109 1≤P,n≤109
Then, for the next T lines, each line consists of 6 integers, A , B, C, D, P, n.
1≤T≤20 0≤A,B,C,D≤109 1≤P,n≤109
输出
output Fn module 109+7.
样例输入
2
3 3 2 1 3 5
3 2 2 2 1 4
样例输出
36
24
矩阵快速幂 问题在于p/i 上图为p=100的表,可以发现p/i相同的连续的一段的最后一个数的坐标为p/(p/i) ,然后分段做就可以了
#include<bits/stdc++.h> #define ll long long using namespace std; const int p=1e9+7; int n,P,T; ll a,b,c,d; struct Mat { ll v[3][3]; Mat() { memset(v, 0, sizeof(v)); } void init() { for (int i=0;i<3;i++) v[i][i]=(ll)1; } }; Mat operator *(Mat a,Mat b) { Mat c; for (int i=0;i<3;i++) { for (int j=0;j<3;j++) { c.v[i][j]=0; for (int k=0;k<3;k++) c.v[i][j]+=((a.v[i][k]%p*b.v[k][j]%p)%p+p)%p; } } return c; } Mat qmod(Mat a,int k) { Mat c; c.init(); while (k) { if (k&1) c=c*a; a=a*a; k>>=1; } return c; } void solve() { scanf("%lld%lld%lld%lld%d%d",&a,&b,&c,&d,&P,&n); Mat mp; mp.v[0][0]=d; mp.v[0][1]=c; mp.v[1][0]=1; mp.v[2][2]=1; for (int i=3;i<=n;) { if(P/i==0) { Mat w=mp; w=qmod(w,n-i+1); cout<<(w.v[0][0]*b+w.v[0][1]*a+w.v[0][2])%p<<endl; return; } int j=min(n,P/(P/i)); Mat w=mp; w.v[0][2]=P/i; w=qmod(w,j-i+1); ll ans_a=(w.v[1][0]*b+w.v[1][1]*a+w.v[1][2])%p; ll ans_b=(w.v[0][0]*b+w.v[0][1]*a+w.v[0][2])%p; a=ans_a;b=ans_b; i=j+1; } printf("%lld\n",b); } int main() { scanf("%d",&T); while (T--) solve(); return 0; }