UVA 12196 Disgruntled Judge 拓展欧几里德算法

62 阅读1分钟

看我手写分析

题目大意:有3个整数 x[1], a, b 满足递推式x[i]=(a*x[i-1]+b)mod 10001。由这个递推式计算出了长度为2T的数列,现在要求输入x[1],x[3],......x[2T-1], 输出x[2],x[4]......x[2T]. T<=100,0<=x<=10000. 如果有多种可能的输出,任意输出一个结果即可。

\

//拓展欧几里德用法详见紫书314页
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
typedef long long LL;
const int mod = 10001;
void ex_gcd(LL a, LL b, LL &d, LL &x, LL &y) {
	if (b == 0) d = a, x = 1, y = 0;
	else {
		ex_gcd(b, a % b, d, y, x);
		y -= x *(a / b);
	}
}
int main()
{
	int n, x[210];
	while (cin >> n) {
		for (int i = 1, j = 1; i <= n; ++i, j += 2)
			cin >> x[j];
		for (LL a = 0; a <= 10000; ++a) { //暴力枚举a 
			LL d, X, Y, c;
			ex_gcd(a + 1, mod, d, X, Y);
			c = x[3] - a * a * x[1];
			if (c % d == 0) { //若 非c|d,无整数解
				bool bingo = true;
				LL b = X * (c / d) % mod;
				for (int i = 1, j = 3; i < n; ++i, j += 2) {
					if (x[j] != (a * (a * x[j - 2] + b) + b) % mod) {
						bingo = false;
						break;
					}
				}
				if (bingo) {
					for (int i = 1, j = 1; i <= n; ++i, j += 2)
						cout << (a * x[j] + b) % mod << endl;
				}
			}
		}
	}

	return 0;
}


\

\

\

\

\