Mike has a frog and a flower. His frog is named Xaniar and his flower is named Abol. Initially(at time 0), height of Xaniar is h1 and height of Abol is h2. Each second, Mike waters Abol and Xaniar.
![](https://i-blog.csdnimg.cn/blog_migrate/fe53d5a0a13bcd430d14047ba104eba6.png)
So, if height of Xaniar is h1 and height of Abol is h2, after one second height of Xaniar will become and height of Abol will become
where x1, y1, x2 and y2 are some integer numbers and
denotes the remainder of amodulo b.
Mike is a competitive programmer fan. He wants to know the minimum time it takes until height of Xania is a1 and height of Abol is a2.
Mike has asked you for your help. Calculate the minimum time or say it will never happen.
The first line of input contains integer m (2 ≤ m ≤ 106).
The second line of input contains integers h1 and a1 (0 ≤ h1, a1 < m).
The third line of input contains integers x1 and y1 (0 ≤ x1, y1 < m).
The fourth line of input contains integers h2 and a2 (0 ≤ h2, a2 < m).
The fifth line of input contains integers x2 and y2 (0 ≤ x2, y2 < m).
It is guaranteed that h1 ≠ a1 and h2 ≠ a2.
Print the minimum number of seconds until Xaniar reaches height a1 and Abol reaches height a2 or print -1 otherwise.
5 4 2 1 1 0 1 2 3
3
1023 1 2 1 0 1 2 1 1
-1
题意:有两个东西,初始高度分别为H1和H2,高度每秒变化,变化满足公式(H*X + Y)mod M。
现给出两个东西的X、Y、M、H,问能否到达高度A,如果能,输出最短时间。
思路:这道题细节特别多。。还好开了小号在div2做。。明明是C题div2居然只有9个人过。。
由线性同余公式知高度变化存在循环节,但是刚开始的一段高度可能不在循环节内,所以先让A或B进入循环节内,这里选择A。
设从H1到A1需要K1秒,如果H1无法到达A1,输出-1;
让B的高度H2也变化K1秒,如果此时H1==A1 && H2 == A2 直接输出K1;
此时H1==A1,从这里开始计算循环节长度,设循环节长度为C,如果从H1出发(最多M次)无法返回A1,说明H1不在循环节内,输出-1;
此后如果可以使H1==A1&&H2==A2,则时间长度一定是C的整数倍;
设x = x2,y = y2
for(i:1 to C)
x = (x * x2)mod M,y = (y * x2 + y2)mod M;
这里的x和y是进行每经过C秒后B的高度变化函数的参数,即下面的f(h)的参数,
f(h)= (xh + y)mod M
枚举B经过若干次C秒变化后的结果,最多M次如果没有达到A2,输出-1;
设经过K2次C秒变化后H2==A2,
所以答案为K2*C+K1
AC代码:
#include <cstdio>
int next(int x, int a, int b, int mod) {
return ((long long)x * a + b) % mod;
}
int main() {
int h1, a1, x1, y1, h2, a2, x2, y2, mod;
scanf("%d\n", &mod);
scanf("%d %d %d %d", &h1, &a1, &x1, &y1);
scanf("%d %d %d %d", &h2, &a2, &x2, &y2);
int k1 = 0, k2 = 0;
while(h1 != a1 && k1 < mod + 10) {//h1到a1经过了k1秒
h1 = next(h1, x1, y1, mod);
h2 = next(h2, x2, y2, mod);
k1++;
}
if(h1 != a1) {
puts("-1");
return 0;
}
if(h1 == a1 && h2 == a2) {
printf("%I64d\n", (long long)k1);
return 0;
}
int cycle = 1;
h1 = next(h1, x1, y1, mod);
int x = x2, y = y2;
while(h1 != a1 && cycle < mod + 10) {//A的循环节为cycle
h1 = next(h1, x1, y1, mod);
cycle++;
x = ((long long)x * x2) % mod;//cycle次变化后x2变为x,y2变为y
y = ((long long)y * x2 + y2) % mod;
}
if(h1 != a1) {
puts("-1");
return 0;
}
while(h2 != a2 && k2 < mod + 10) {//经过k2次cycle秒变化后h2==a2
h2 = next(h2, x, y, mod);
k2++;
}
if(h2 != a2) {
puts("-1");
return 0;
}
printf("%I64d\n", (long long) k2 * cycle + k1);
return 0;
}