Descripción del título
Solución
La sala de examen adivinó que la sección de bucle era \ (3p \ varphi (p) \) y luego era falsa
Observe que g [n] = a * f [algún elemento] + b * f [otro elemento], f representa la secuencia de Fibonacci
Y la posición de f en g [n] yg [n + 1] es exactamente 2
El elemento específico no es importante , solo importa la diferencia 2
Prueba:
\ (- f [n-4] + 3f [n-2] = f [n-3] + 2f [n-2] = f [n-2] + f [n-1] = f [n] \ )
Ambos f ingresan 2 cada vez, por lo que la sección de bucle de g es en realidad la sección de bucle de f
Solo son algunas pruebas para memorizar el contenido de este documento
El requisito es g [g [g [g [... g [n]]]]]% p, el modo p solo está en la primera capa, por lo que el interior puede ser muy grande
Debido a que la primera capa es módulo p, la segunda capa puede ser módulo (la sección cíclica de p), luego descender a su vez y finalmente encontrar el módulo g [n]% y traerlo de vuelta.
p no se fríe, tómalo con calma
código
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define abs(x) ((x)>0?(x):-(x))
#define N 31622
#define ll long long
#define file
using namespace std;
struct mat{
ll a[2][2];
void clear() {memset(a,0,sizeof(a));}
} a,b,one,turn;
int A[20],B[20],p[N+1],T,i,j,k,l,K,mod,x,y,tot,s,S,len;
bool f[N+1];
ll n,Mod;
ll qpower(ll a,int b,ll mod) {ll ans=1;while (b) {if (b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;} return ans;}
mat mul(mat &a,mat b,ll mod)
{
int i,j,k;
mat c;
fo(i,0,1)
{
fo(j,0,1)
{
c.a[i][j]=0;
fo(k,0,1)
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
}
}
return c;
}
void init()
{
int i,j,k,l;
fo(i,2,N)
{
if (!f[i]) p[++len]=i;
fo(j,1,len)
if (i*p[j]<=N)
{
f[i*p[j]]=1;
if (!(i%p[j])) break;
}
else
break;
}
}
ll js(int t)
{
ll S;
if (t==2) S=3;
else
if (t==3) S=8;
else
if (t==5) S=20;
else
if (t%5==1 || t%5==4) S=t-1;
else
S=2*(t+1);
return S;
}
ll gcd(ll x,ll y)
{
ll r=x%y;
while (r) x=y,y=r,r=x%y;
return y;
}
ll lcm(ll x,ll y) {return x*y/gcd(x,y);}
ll work(int t,ll mod)
{
ll s=mod,Mod=1,S,s2,n;
int i,j,k,l;
if (t>1)
{
fo(i,1,len)
if (!(s%p[i]))
{
s2=1;
while (!(s%p[i])) s/=p[i],s2*=p[i];
s2/=p[i];
Mod=lcm(Mod,js(p[i])*s2);
if (s==1) break;
}
if (s>1) Mod=lcm(Mod,js(s));
n=work(t-1,Mod);
}
else
n=::n;
a=one;b=turn;
while (n)
{
if (n&1) a=mul(a,b,mod);
b=mul(b,b,mod);
n>>=1;
}
return ((a.a[0][0]*x+a.a[1][0]*y)%mod+mod)%mod;
}
int main()
{
freopen("hakugai.in","r",stdin);
#ifdef file
freopen("hakugai.out","w",stdout);
#endif
one.a[0][0]=1;one.a[0][1]=0;
one.a[1][0]=0;one.a[1][1]=1;
turn.a[0][0]=0;turn.a[0][1]=-1;
turn.a[1][0]=1;turn.a[1][1]=3;
init();
scanf("%d",&T);
for (;T;--T)
{
scanf("%d%d%d%d%d",&x,&y,&n,&K,&mod); s=floor(sqrt(mod));Mod=mod;
printf("%lld\n",work(K,mod));
}
fclose(stdin);
fclose(stdout);
return 0;
}