Codeforces Round #305 C. Mike and Frog

C. Mike and Frog
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

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.

Input

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.

Output

Print the minimum number of seconds until Xaniar reaches height a1 and Abol reaches height a2 or print -1 otherwise.

Sample test(s)
input
5
4 2
1 1
0 1
2 3
output
3
input
1023
1 2
1 0
1 2
1 1
output
-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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值