For a sequence X. Xn+1 = ( a * Xn + c ) % p. Now given a, c, X0, n, p, you need to calculate Xn. Input The first line contains an integer T, indicating that there are T test cases (T <= 20); Output For each test case, output the integer Xn. Sample Input Sample Output |
//由于n=1e18,直接做会超时,用矩阵快速幂,构造:
a,c x0,0 x1,0
0,1 * 1 ,0 = 1 ,0
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
ll b,c,x0,n,p;
struct mat
{
ll a[2][2];
};
mat mul(mat x,mat y)
{
mat ans;
memset(ans.a,0,sizeof(ans.a));
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
for(int k=0;k<2;k++)
{
ans.a[i][j]=((ans.a[i][j]+((x.a[i][k]%p)*y.a[k][j])%p))%p;
}
}
}
return ans;
}
ll fastpowerMod(ll n)
{
mat s;
memset(s.a,0,sizeof(s.a));
for(int i=0;i<2;i++)s.a[i][i]=1;
mat res;
memset(res.a,0,sizeof(res.a));
res.a[0][0]=b;
res.a[0][1]=c;
res.a[1][0]=0;
res.a[1][1]=1;
while(n!=0)
{
if(n%2==1)
s=mul(s,res);
res=mul(res,res);
n=n>>1;
}
mat result;
result.a[0][0]=x0;
result.a[1][0]=1;
result.a[0][1]=result.a[1][1]=0;
result=mul(s,result);
return result.a[0][0];
}
int main()
{
ll t;
while(~scanf("%lld",&t))
{
while(t--)
{
scanf("%lld%lld%lld%lld%lld",&b,&c,&x0,&n,&p);
if(n==0)
printf("%lld\n",x0);
else
printf("%lld\n",fastpowerMod(n));
}
}
return 0;
}