題目
題目鏈接:http://codeforces.com/problemset/problem/548/C
題目來源:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105944#problem/L
簡要題意:求倆同餘方程是否會同時成立,如果可以,求出最小的那個成立的值。
題解
首先去判斷兩個方程是否能夠成立,次數的上限是
m 。然後去算回到自己的循環節,就是達到
a 後多久再回到a 。然後最後根據已有的信息去暴力加上循環節然後去判斷,上限還是
m 。題目相當坑,做起來要考慮許多邊界的情況。
代碼
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
// head
int mul(int h, int x, int y, int m) {
return (LL(x) * h + y) % m;
}
int findPeriod(int h, int a, int x, int y, int m) {
for (int i = 1; i <= m; i++) {
h = mul(h, x, y, m);
if (h == a) return i;
}
return 0;
}
LL solve(LL rem1, int rem2, int per1, int per2, int m) {
for (int i = 0; i <= m; i++) {
if (rem1 >= rem2 && (rem1-rem2) % per2 == 0) return rem1;
rem1 += per1;
}
return -1;
}
int main() {
int m, x1, y1, h1, a1, x2, y2, h2, a2;
scanf("%d", &m);
scanf("%d%d%d%d", &h1, &a1, &x1, &y1);
scanf("%d%d%d%d", &h2, &a2, &x2, &y2);
int rem1 = findPeriod(h1, a1, x1, y1, m);
int rem2 = findPeriod(h2, a2, x2, y2, m);
if (!rem1 || !rem2) {
puts("-1");
return 0;
}
int per1 = findPeriod(a1, a1, x1, y1, m);
int per2 = findPeriod(a2, a2, x2, y2, m);
if (rem1 > rem2) {
swap(rem1, rem2);
swap(per1, per2);
}
if (rem1 == rem2 || (per1 && (rem2-rem1)% per1 == 0)) {
printf("%d\n", rem2);
} else if (!per1 || !per2) {
puts("-1");
} else {
printf("%I64d\n", solve(rem1, rem2, per1, per2, m));
}
return 0;
}