Codeforces Round #305 (Div. 2)C---Mike and Frog(扩欧+乱搞)

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 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 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

Note

In the first sample, heights sequences are following:

Xaniar:

Abol:

m次以内一定有循环节,否则没周期

所以可以搞出循环节,之后可以得到一个二元一次方程,扩欧求解

找一个最小解即可

/*************************************************************************
    > File Name: C.cpp
    > Author: ALex
    > Mail: [email protected]
    > Created Time: 2015年05月27日 星期三 16时15分01秒
 ************************************************************************/

#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>

using namespace std;

const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

int vis[1001010];

void ex_gcd(int a, int b, int &x, int &y) {
    if (!b) {
        x = 1;
        y = 0;
    }
    else {
        ex_gcd(b, a % b, y, x);
        y -= x * (a / b);
    }
}

int gcd(int a, int b) {
    return b ? gcd(b, a % b) : a;
}

int main() {
    int m;
    while (~scanf("%d", &m)) {
        int h1, a1, x1, y1;
        int h2, a2, x2, y2;
        scanf("%d%d%d%d", &h1, &a1, &x1, &y1);
        scanf("%d%d%d%d", &h2, &a2, &x2, &y2);
        for (int i = 0; i <= m; ++i) {
            vis[i] = -1;
        }
        int s1 = -1;
        vis[h1] = 0;
        LL cur = h1;
        int len1 = 0;
        for (int i = 1; i <= m; ++i) {
            cur = (cur * x1 + y1) % m;
            if (vis[cur] == -1) {
                vis[cur] = i;
                if (cur == a1) {
                    s1 = i;
                }
            }
            else {
                len1 = i - vis[cur];
                break;
            }
        }
        if (s1 == -1) {
            printf("-1\n");
            continue;
        }
        cur = a1;
        bool flag1 = 0;
        for (int i = s1 + 1; i <= len1 + s1; ++i) {
            cur = (cur * x1 + y1) % m;
        }
        if (cur == a1) {
            flag1 = 1;
        }
        cur = h2;
        int len2 = 0;
        int s2 = -1;
        for (int i = 0; i <= m; ++i) {
            vis[i] = -1;
        }
        vis[h2] = 0;
        for (int i = 1; i <= m;++i) {
            cur = (cur * x2 + y2) % m;
            if (vis[cur] == -1) {
                vis[cur] = i;
                if (cur == a2) {
                    s2 = i;
                }
            }
            else {
                len2 = i - vis[cur];
                break;
            }
        }
        if (s2 == -1) {
            printf("-1\n");
            continue;
        }
        bool flag2 = 0;
        cur = a2;
        for (int i = s2 + 1; i <= s2 + len2; ++i) {
            cur = (cur * x2 + y2) % m;
        }
        if (cur == a2) {
            flag2 = 1;
        }
        if (!flag1 && !flag2) {
            if (s1 == s2) {
                printf("%d\n", s1);
            }
            else {
                printf("-1\n");
            }
            continue;
        }
        if (!flag1 && flag2) {
            if (s1 < s2) {
                printf("-1\n");
            }
            else {
                if ((s1 - s2) % len2) {
                    printf("-1\n");
                }
                else {
                    printf("%d\n", s1);
                }
            }
            continue;
        }
        if (flag1 && !flag2) {
            if (s1 > s2) {
                printf("-1\n");
            }
            else {
                if ((s2 - s1) % len1) {
                    printf("-1\n");
                }
                else {
                    printf("%d\n", s2);
                }
            }
            continue;
        }
        int GCD = gcd(len1, len2);
        if ((s2 - s1) % GCD) {
            printf("-1\n");
            continue;
        }
        int x0, y0;
        ex_gcd(len1, len2, x0, y0);
        x0 = x0 * (s2 - s1) / GCD;
        y0 *= -1;
        y0 = y0 * (s2 - s1) / GCD;
        int b = len2 / GCD;
        int a = len1 / GCD;
        if (x0 < 0) {
            LL k = ceil(-1.0 * x0 / b);
            x0 += k * b;
            y0 += k * a;
        }
        if (y0 < 0) {
            LL k = ceil(-1.0 * y0 / a);
            x0 += k * b;
            y0 += k * a;
        }
        LL ans = (LL)y0 * len2 + s2;
        while (1) {
            if (y0 - a >= 0) {
                y0 -= a;
                x0 -= b;
                ans = (LL)y0 * len2 + s2;
            }
            else {
                break;
            }
        }
        cout << ans << endl;
    }
    return 0;
}
时间: 2024-10-14 15:22:17

Codeforces Round #305 (Div. 2)C---Mike and Frog(扩欧+乱搞)的相关文章

数论/暴力 Codeforces Round #305 (Div. 2) C. Mike and Frog

题目传送门 1 /* 2 数论/暴力:找出第一次到a1,a2的次数,再找到完整周期p1,p2,然后以2*m为范围 3 t1,t2为各自起点开始“赛跑”,谁落后谁加一个周期,等到t1 == t2结束 4 详细解释:http://blog.csdn.net/u014357885/article/details/46044287 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cstring> 9 #in

Codeforces Round #305 (Div. 2) C. Mike and Frog +B. Mike and Fun

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 

暴力 Codeforces Round #305 (Div. 2) B. Mike and Fun

题目传送门 1 /* 2 暴力:每次更新该行的num[],然后暴力找出最优解就可以了:) 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <iostream> 7 #include <algorithm> 8 #include <string> 9 using namespace std; 10 11 const int MAXN = 5e2 + 10; 12 const int

set+线段树 Codeforces Round #305 (Div. 2) D. Mike and Feet

题目传送门 1 /* 2 题意:对于长度为x的子序列,每个序列存放为最小值,输出长度为x的子序列的最大值 3 set+线段树:线段树每个结点存放长度为rt的最大值,更新:先升序排序,逐个添加到set中 4 查找左右相邻的位置,更新长度为r - l - 1的最大值,感觉线段树结构体封装不错! 5 详细解释:http://blog.csdn.net/u010660276/article/details/46045777 6 其实还有其他解法,先掌握这种:) 7 */ 8 #include <cstd

字符串处理 Codeforces Round #305 (Div. 2) A. Mike and Fax

题目传送门 1 /* 2 字符串处理:回文串是串联的,一个一个判断 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <iostream> 7 #include <algorithm> 8 #include <string> 9 using namespace std; 10 11 const int MAXN = 1e3 + 10; 12 const int INF = 0x3f3

Codeforces Round #305 (Div. 1) B. Mike and Feet

Mike is the president of country What-The-Fatherland. There are n bears living in this country besides Mike. All of them are standing in a line and they are numbered from 1 to n from left to right. i-th bear is exactly ai feet high. A group of bears

Codeforces Round #305 (Div. 2) E. Mike and Foam 容斥原理

在一个集合中,找和x互素的数有多少? 用容斥定理,先把每个数质因数分解(每个数至多有6个质因子),奇减偶加,就统计到和x互素的数了. 代码: #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int N = 5*100000+10; const int maxn

Codeforces Round #305 (Div. 1) B. Mike and Feet(并查集)

题目链接:点击打开链接 思路:我们把元素从大到小排序, 从大到小依次合并区间, 对于第i个数, 如果他相邻左边的数比他大就合并, 相邻右边也一样.这样, 我们就求出了第i个数为最小值的最大区间. 更新答案即可. 细节参见代码: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <string> #include <ve

Codeforces Round #305 (Div. 1)C. Mike and Foam(素数+容斥)

题目链接:点这里!!! 题意: 输入n(n<=2e5),q(q<=2e5).紧接着输入n个数a1~an(ai<=5e5).给定一个空集合. 针对每个q,输入x,如果a[x]在不在集合里面,将a[x]插入进去,并且求当前该集合中有多少对互质的数: 如果a[x]在集合里面,将a[x]删除,并且求当前该集合有多少对互质的数. 题解: 1. 将所有数的素因子求出来.(最多6个) 2.如果将a[x]插入进去,我们检查由a[x]的素因子能组成的数有哪些,全部+1. 比如a[x]=12,我们将2.3.