您的位置:首页 > 其它

Codeforces #305 C. Mike and Frog 数论

2016-03-01 14:09 330 查看

题目

题目链接:http://codeforces.com/problemset/problem/548/C

题目来源:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105944#problem/L

简要题意:求俩同余方程是否会同时成立,如果可以,求出最小的那个成立的值。

题解

首先去判断两个方程是否能够成立,次数的上限是mm。

然后去算回到自己的循环节,就是达到aa后多久再回到aa。

然后最后根据已有的信息去暴力加上循环节然后去判断,上限还是mm。

题目相当坑,做起来要考虑许多边界的情况。

代码

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: