UVA 12169 Disgruntled Judge (扩展欧几里得)

版权声明:希望能在自己成长的道路上帮到更多的人,欢迎各位评论交流 https://blog.csdn.net/yiqzq/article/details/82156012

原题地址:here

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

思路:因为题目中 a 的数据范围只有 1 e 4 ,所以我们可以通过枚举 a 去确定 b ,那么如何去求 b 呢?
我们可以通过扩展欧几里得算法去求解线性同余方程.

#include <bits/stdc++.h>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)+1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 1e5 + 5;
const int mod = 10001;
ll x, y;
ll d1[maxn];
ll d2[maxn];
int n;
ll exgcd(ll a, ll b, ll &x, ll &y) { //求解ax+by=gcd(a,b)
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    ll ans = exgcd(b, a % b, x, y);
    ll temp = x;
    x = y;
    y = temp - (a / b) * y;
    return ans;
}


bool check(ll a, ll b) {
    for (int i = 1; i <= n; i++) {
        d2[i] = (d1[i] * a + b)%mod;
        if (i != n) {
            if (d1[i + 1] != (a * d2[i] + b) % mod) return 0;
        }
    }
    return 1;
}
int main() {

    while (~scanf("%d", &n)) {
        int f = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%lld", &d1[i]);
        }
        for (ll i = 0; i <= 10000; i++) {//枚举a
            ll gcd = exgcd((i + 1), 10001, x, y);

            ll sum = d1[2] - i * i * d1[1];//注意这里会爆int,因此要开long long
            if (sum % gcd) continue;
            ll b = x * sum / gcd;
            f = check(i, b);
            if (f) break;
        }
        for (int i = 1; i <= n; i++) printf("%lld\n", d2[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yiqzq/article/details/82156012