http://acm.hdu.edu.cn/showproblem.php?pid=6395
看公式我们可以发现对于一个n,可以分成若干块,这若干块的p/n向下取整都是相同的。那么就可以矩阵快速幂了。
比如100 可以分成100-51 50-34 33-26 。。。。。。
可以用二分来划分块。
#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
struct node{
long long md[3][3];
};
long long jl[11];
node operator * (node x,node y)
{
node c;
memset(c.md,0,sizeof(c.md));
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
for(int k=0;k<3;k++)
{
c.md[i][j]=(c.md[i][j]+x.md[i][k]*y.md[k][j]%mod)%mod;
}
}
}
return c;
}
node qpow(node x,long long cs)
{
node ans=x;
cs--;
while(cs)
{
if(cs&1)
ans=ans*x;
x=x*x;
cs>>=1;
}
return ans;
}
int main(){
int t;
scanf("%d",&t);
while(t--)
{
long long a,b,c,d,p,n;
scanf("%lld %lld %lld %lld %lld %lld",&a,&b,&c,&d,&p,&n);
jl[1]=a;
jl[2]=b;
if(n<=2)
{
printf("%lld\n",jl[n]%mod);
continue;
}
long long l=3;
long long r;
if(p<=2)
{
long long key=0;
long long cs=n-2;
node st;
st.md[0][0]=0;
st.md[0][1]=1;
st.md[0][2]=0;
st.md[1][0]=c;
st.md[1][1]=d;
st.md[1][2]=1;
st.md[2][0]=0;
st.md[2][1]=0;
st.md[2][2]=1;
st=qpow(st,cs);
long long fp1=a;
long long fp2=b;
a=(st.md[0][0]%fp1%mod+st.md[0][1]*fp2%mod+st.md[0][2]*key%mod)%mod;
b=(st.md[1][0]*fp1%mod+st.md[1][1]*fp2%mod+st.md[1][2]*key%mod)%mod;
printf("%lld\n",b%mod);
continue;
}
else {
while(1)
{
if(l>p)
{
long long key=0;
long long cs=n-p;
node st;
st.md[0][0]=0;
st.md[0][1]=1;
st.md[0][2]=0;
st.md[1][0]=c;
st.md[1][1]=d;
st.md[1][2]=1;
st.md[2][0]=0;
st.md[2][1]=0;
st.md[2][2]=1;
st=qpow(st,cs);
long long fp1=a;
long long fp2=b;
a=(st.md[0][0]%fp1%mod+st.md[0][1]*fp2%mod+st.md[0][2]*key%mod)%mod;
b=(st.md[1][0]*fp1%mod+st.md[1][1]*fp2%mod+st.md[1][2]*key%mod)%mod;
printf("%lld\n",b%mod);
break;
}
else{
long long dq=p/l;
long long zr;
if(dq==1)
{
zr=p;
}
else{
long long el=l;
long long er=p;
long long mid;
while(el<er)
{
mid=(el+er+1)/2;
long long css=p/mid;
if(css<dq)
{
er=mid-1;
}
else el=mid;
}
zr=el;
}
r=zr;
long long key=p/l;
node st;
st.md[0][0]=0;
st.md[0][1]=1;
st.md[0][2]=0;
st.md[1][0]=c;
st.md[1][1]=d;
st.md[1][2]=1;
st.md[2][0]=0;
st.md[2][1]=0;
st.md[2][2]=1;
if(n>r)
{
long long cs=r-l+1;
st=qpow(st,cs);
long long fp1=a;
long long fp2=b;
a=(st.md[0][0]*fp1%mod+st.md[0][1]*fp2%mod+st.md[0][2]*key%mod)%mod;
b=(st.md[1][0]*fp1%mod+st.md[1][1]*fp2%mod+st.md[1][2]*key%mod)%mod;
l=r+1;
}
else{
long long cs=n-l+1;
st=qpow(st,cs);
long long fp1=a;
long long fp2=b;
a=(st.md[0][0]*fp1%mod+st.md[0][1]*fp2%mod+st.md[0][2]*key%mod)%mod;
b=(st.md[1][0]*fp1%mod+st.md[1][1]*fp2%mod+st.md[1][2]*key%mod)%mod;
printf("%lld\n",b%mod);
break;
}
}
}
}
}
return 0;
}