Codeforces548C:Mike and Frog

来源:互联网 发布:录像软件app 编辑:程序博客网 时间:2024/04/29 05:04

原题链接

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(x1h1 + y1)mod m and height of Abol will become (x2h2 + y2)mod m where x1, y1, x2 and y2 are some integer numbers and a mod bdenotes the remainder of a modulo 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 Input

Input

54 21 10 12 3

Output

3

Input

10231 21 01 21 1

Output

-1

Hint

In the first sample, heights sequences are following:Xaniar: 4 → 0 → 1 → 2Abol: 0 → 3 → 4 → 1

这道题是说Mike有一只青蛙叫Xaniar,还有一棵花叫 Abol。青蛙每过一天高度变为(x1h1 + y1)mod m,花每过一天高度变为(x2h2 + y2)mod m。问,什么时候青蛙的高度能达到a1并且花的高度变成a2
怎么解呢?(@﹏@)~
一种方法是先求第一次到达a1的时间,然后再求循环节,由于是mod运算,一定会有一个最小的循环节的。青蛙和花的第一次达到目标高度的时间和循环节都求出来之后,然后就暴力算就行了。
上代码~ o(* ̄︶ ̄*)o

 #include <stdio.h> #include <bits/stdc++.h>using namespace std;long long cycle1, cycle2;int main(){ #ifndef ONLINE_JUDGE    freopen("1.txt", "r", stdin); #endif    long long h1, a1, x1, y1, h2, a2, x2, y2,i;    long long flag1, flag2;    int m;    while(~scanf("%d", &m))    {        scanf("%I64d%I64d%I64d%I64d", &h1, &a1, &x1, &y1);        scanf("%I64d%I64d%I64d%I64d", &h2, &a2, &x2, &y2);        cycle1 = 0;        cycle2 = 0;        flag1 = 0;        flag2 = 0;        for (i = 1; i <= 2*m; i++)        {            h1 = (x1*h1+y1)%m;            if (h1 == a1)            {                if (!flag1)                {                    flag1 = i;                }                else if (!cycle1)                {                    cycle1 = i - flag1;                }            }               h2 = (x2*h2+y2)%m;            if (h2 == a2)            {                if (!flag2)                {                    flag2 = i;                }                else if (!cycle2)                {                    cycle2 = i - flag2;                }            }            if (cycle1 && cycle2)            {                break;            }           }        if (!flag1 || !flag2)        {            printf("-1\n");        }        else if (flag1 == flag2)        {            cout << flag1 << endl;;        }        else        {            for(i = 0; i <= 2*m; i++)            {                if (flag1 < flag2)                {                    flag1 += cycle1;                }                else                {                    flag2 += cycle2;                }                if (flag1 == flag2)                {                    cout << flag1 << endl;                    return 0;                }            }            cout << "-1" << endl;        }    }    return 0;} 

不过,传说还有一种比较牛X的做法:扩展欧几里得



对,就是扩展欧几里得

PS:一下内容出自这里

用于处理计算ax+by = c 的x,y的值
由已知数据我们容易可以的出flag1,cycle1,flag2,cycle2,依次是h1到a1的开始的时间,循环的时间,h2到a2的开始的时间,循环的时间,那么可以得到flag1x+cycle1 = flag2x+cycle2

变形可得 cycle1x-cycle2x=flag2-flag1

欧几里得 ax+b = c gcd(a,b) = gcd(b,a%b)
当b=0时就是最大公约数,递归最大公约数的求法

int gcd(int a,int b){    return b == 0 ? a : gcd(b, a % b);}
拓展欧几里得公式 ax+by=c

int   exgcd(int  a,int  b){    if(b == 0){        x = 1;        y = 0;        return a;    }    int  d = exgcd(b,a%b);    int  t = x;    x = y;    y = t - a/b*y;    return d;}

可以得到其中一个x,y的解(对于ax+by = gcd(a,b) 这个方程)

定理:对于ax+by = gcd(a,b)来说肯定会存在x,y(为正整数)的解

所以最终的解为 x = c/d,y =c/d;如果c%d!=0说明无正整数解

那么对于所有的x,y解集满足条件

x = x + flag2/d;

y = y - flag1/d;

对于本题来说只要找到一个最小的x满足x,y都大于等于零,res = cycle1x+flag1
以上都是些结论
详情查看大神的博客

0 0