Sequence(分段+矩陣快速冪)
阿新 • • 發佈:2019-02-10
Sequence
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1857 Accepted Submission(s): 716
#include<bits/stdc++.h> using namespace std; #define ll long long #define line cout<<"-------------------------"<<endl; #define clr(a) memset(a,0,sizeof(a)) const int MAXN = 1e5+10; const int INF = 0x3f3f3f3f; const int Mod = 1e9+7; const int N = 3; ll t,n,a,b,c,d,p; struct Matrix{//定義N*N的矩陣 ll m[N][N]; }ans; Matrix Mul(Matrix a,Matrix b){//定義矩陣乘法。 Matrix c; memset(c.m,0,sizeof(c.m)); for(int i=0;i<N;i++) for(int j=0;j<N;j++) for(int k=0;k<N;k++) c.m[i][j] += ((a.m[i][k]*b.m[k][j])%Mod + Mod)%Mod; return c; } Matrix fastm(Matrix a,int n) {//矩陣的快速冪 Matrix res;//定義一個單位矩陣 clr(res.m); for(int i=0;i<3;i++) res.m[i][i] = 1;//利用單位矩陣求解 while(n){//快速冪 if(n&1) res = Mul(res,a); n>>=1; a = Mul(a,a); } return res;//求出a^n } int main(){ scanf("%lld",&t); while(t--){ scanf("%lld%lld%lld%lld%lld%lld",&a,&b,&c,&d,&p,&n); clr(ans.m); ans.m[0][0] = d;ans.m[0][1] = c; ans.m[1][0] = ans.m[2][2] = 1; int flag = 0; if(n == 1){ printf("%lld\n",a); continue; } if(n == 2){ printf("%lld\n",b); continue; } for(int i=3;i<=n;){ if(p/i == 0){//最後的部分 Matrix w = ans; w = fastm(w,n-i+1); ll cnt = w.m[0][0]*b%Mod + w.m[0][1]*a%Mod + w.m[0][2]%Mod; cnt %= Mod; printf("%lld\n",cnt); flag = 1;break; } int j = min(n,p/(p/i)); Matrix w = ans; w.m[0][2] = p/i; w = fastm(w,j-i+1); ll u = (w.m[1][0]*b + w.m[1][1]*a + w.m[1][2]) % Mod; ll v = (w.m[0][0]*b + w.m[0][1]*a + w.m[0][2]) % Mod; a = u;b = v;//更新 i = j+1; } if(!flag) printf("%lld\n",b); } return 0; }