给出x1、y1、x2、y2,m,h1,h2,a1,a2,问经过多少次迭代:h1=(h1*x1+y1)%m,h2=(h2*x2+y2)%m,使得h1=a1且h2=a2。若不能得到,输出-1.
找到h1->a1需要的次数a,a1->a1的次数b,h2->a2的次数c,a2->a2的次数d。
然后就是看是否存在x、y使得bx+a=cy+b
直接模拟就好了。首先分别判断h1、h2经过不超过2m次迭代能否得到a1,a2。为什么是2m次?因为模m,最多有0-m-1共m种结果,考虑最坏的情况前m次迭代得到了m种不同的结果,则最多还需要迭代m次,便能够得到循环节。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL m,x1,y1,a1,a2,x2,y2,h1,h2;
LL solve(){
LL s1=0,ss1=0,s2=0,ss2=0;
bool f1=1,f2=1;
do{
if(s1>2*m) return -1;
h1=(h1*x1+y1)%m;
++s1;
}while(h1!=a1);
do{
if(s2>2*m) return -1;
h2=(h2*x2+y2)%m;
++s2;
}while(h2!=a2);
do{
if(ss1>2*m) {f1=0;break;}
h1=(h1*x1+y1)%m;
++ss1;
}while(h1!=a1);
do{
if(ss2>2*m) {f2=0;break;}
h2=(h2*x2+y2)%m;
++ss2;
}while(h2!=a2);
LL ans;
if(f1&&f2){
for(int i=0;i<=2*m;++i){
ans=s1+i*ss1;
if(ans>=s2&&(ans-s2)%ss2==0) return ans;
}
}
else if(f1){
for(int i=0;i<=2*m;++i){
ans=s1+i*ss1;
if(ans==s2) return ans;
}
}
else if(f2){
for(int i=0;i<=2*m;++i){
ans=s2+i*ss2;
if(ans==s1) return ans;
}
}
else{
if(s1==s2) return ans;
}
return -1;
}
int main()
{
cin>>m>>h1>>a1>>x1>>y1>>h2>>a2>>x2>>y2;
printf("%lld\n",solve());
return 0;
}