这道题emmmmmmn…
比赛的时候想到矩阵快速幂了,但分段这个真的是…不好想更不好敲。。后来看了标程,豁然开朗Orz
只能说明。。我好菜啊啊啊啊啊555555…
递推式如下:(x是不断更新的量)
| f(n) | | D C x | | f(n-1) |
| f(n-1) | = | 1 0 0 | * | f(n-2) |
| 1 | | 0 0 1 | | 1 |
有个bug就是矩阵相乘的时候顺序反了,一般矩阵是不满足交换律的,所以一定要注意。
附上AC代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
using namespace std;
#define ll long long
const ll MOD=1e9+7;
ll A,B,C,D,P,n;
struct mat
{
ll a[3][3];
}c,ans,unit;
mat mul(mat x,mat y,ll n)//注意x,y的顺序!!!
{
mat cnt;
memset(cnt.a,0,sizeof(cnt.a));
for(ll i=0;i<n;i++)
for(ll j=0;j<n;j++)
for(ll k=0;k<n;k++)
cnt.a[i][j]=(cnt.a[i][j]+x.a[i][k]*y.a[k][j]%MOD)%MOD;
return cnt;
}
mat Pow(mat c,ll k)
{
mat res;
memcpy(res.a,unit.a,sizeof(res.a));
while(k>0)
{
if(k&1)
res=mul(res,c,3);
c=mul(c,c,3);
k=(k>>1);
}
return res;
}
void init(ll x)
{
c.a[0][0]=D;c.a[0][1]=C;c.a[0][2]=x;
c.a[1][0]=1;c.a[1][1]=0;c.a[1][2]=0;
c.a[2][0]=0;c.a[2][1]=0;c.a[2][2]=1;
return;
}
int main()
{
memset(unit.a,0,sizeof(unit.a));
for(int i=0;i<3;i++)
unit.a[i][i]=1;
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);
else if(n==2)
printf("%lld\n",B);
else if(n<P)
{
ans=unit;
for(ll i=3;i<=n;i=P/(P/i)+1)
{
init(P/i);
if(n<=P/(P/i))
c=Pow(c,n-i+1);
else
c=Pow(c,P/(P/i)+1-i);
ans=mul(c,ans,3);
}
ll aans=(ans.a[0][0]*B%MOD+ans.a[0][1]*A%MOD+ans.a[0][2]%MOD)%MOD;
cout<<aans<<endl;
}
else if(P<=n)
{
ans=unit;
for(ll i=3;i<=P;i=P/(P/i)+1)
{
init(P/i);
c=Pow(c,P/(P/i)+1-i);
ans=mul(c,ans,3);
}
init(0);
c=Pow(c,n-max(P,(ll)2));
ans=mul(c,ans,3);
ll aans=(ans.a[0][0]*B%MOD+ans.a[0][1]*A%MOD+ans.a[0][2]%MOD)%MOD;
cout<<aans<<endl;
}
}
return 0;
}