分块加矩阵快速幂
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; typedef long long ll; const int mod=1e9+7; int a,b,c,d,p,n; struct node { int m[3][3]; node() { memset(m, 0, sizeof(node)); } friend node operator*(node a, node b) { node c; for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { ll t = 0; for(int k=0; k<3; k++) { t += (ll)a.m[i][k]*b.m[k][j]; } c.m[i][j] = t%mod; } } return c; } } I; node qpow(node a,int b) { node c=I; while(b) { if(b&1) c=c*a; a=a*a; b>>=1; } return c; } int main() { int i,j,k,t; scanf("%d",&t); I.m[0][0]=1; I.m[1][1]=1; I.m[2][2]=1; while(t--) { scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&p,&n); if(n==1) { printf("%d\n",a); continue; } node f; f.m[0][0]=d; f.m[0][1]=c; f.m[1][0]=1; f.m[2][2]=1; int flag=0; for(i=3;i<=n;) { if(p/i==0) { node w=f; w=qpow(w,n-i+1); ll ans=1ll*b*w.m[0][0]%mod+1ll*a*w.m[0][1]%mod; ans=ans%mod; printf("%lld\n",ans); flag=1; break; } j=min(n,p/(p/i)); node w=f; w.m[0][2]=p/i; w=qpow(w,j-i+1); ll temp1=1ll*b*w.m[1][0]%mod+1ll*a*w.m[1][1]%mod+w.m[1][2]; ll temp2=1ll*b*w.m[0][0]%mod+1ll*a*w.m[0][1]%mod+w.m[0][2]; a=temp1%mod; b=temp2%mod; i=j+1; } if(!flag) printf("%d\n",b); } return 0; }