UVA.12169 Disgruntled Judge ( 拓展欧几里得 )

UVA.12169 Disgruntled Judge ( 拓展欧几里得 )

题意分析

给出T个数字,x1,x3……x2T-1。并且我们知道这x1,x2,x3,x4……x2T之间满足xi = (a * xi-1 + b ) MOD 10001, 求出x2,x4……x2T.

由于本题中的a和b是未知的,所以需要根据已知条件求出a和b,据说有人暴力枚举a和b然后过了。 所以我来换另一种方法。

其实我们可以枚举a,并根据x1,x3算出求出可行的b的值。如何做到呢?

首先我们已经知道
x2 = (a * x1 + b) MOD 10001
x3 = (a * x2 + b) MOD 10001
于是就可以把第一个式子带入到第二个式子中,消去x2,进而得到
x3 = ( a * (a * x1 + b) + b ) MOD 10001
而这个式子,可以进一步转化为

思考一下为什么,等式左边是10001 * k + x3, 对10001 取模后,不就是x3吗? 一开始没有想到,要熟记这个转化!

对于式子x3 + 10001 * k = ( a * (a * x1 + b) + b ) ,继续稍作化简,可以得到
(a+1) * b - 10001 * k = x3 - a * a * x1

而这个式子,就可以用拓展欧几里得算法,求得一组可行解(b,k),我们比较关心的是b的值,在计算完成之后,要记得检验 (x3 - a * a * x1) / gcd( (a+1),10001) 是否为整数,若是的话,就说明这对(a,b) 对于x1,x3是可行的。

然而题目还给出了x5……等等的奇数序列,我们在依次递推的时候,若发现求出的x5,x7……与原数列不相等,那么说明求出的(a,b)并不work,还要重新求解,题目保证一定有解。

代码总览

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#define ll long long
#define nmax 220
#define MOD 10001
using namespace std;
ll a,b,k,c,d;
int n;
ll x[nmax];
void exgcd(ll a, ll b, ll& d, ll& x, ll &y){
    if(!b){
        d = a,x = 1,y = 0;
    }else{
        exgcd(b, a % b, d, y, x);
        y -= x * (a / b);
    }
}
bool solve(){
    c = x[3] - a*a*x[1];
    exgcd(a+1,MOD,d,b,k);
    if(c % d == 0){
        b = c / d * b;
        return true;
    }
    else return false;

}
int main()
{
    //freopen("in.txt","r",stdin);
    while(scanf("%d",&n) != EOF){
        for(int i =1;i<=2*n;i+=2) scanf("%lld",&x[i]);
        bool isfindall = false;
        for( a = 0;a < MOD;++a){
            if(solve()){
                for(int j = 2;j<=2*n;++j){
                    isfindall = false;
                    ll tmp = ( (a * x[j-1]) + b)%MOD;
                    if( (j%2!=0) && tmp != x[j]) break;
                    else x[j] = tmp;
                    if(j == 2*n) isfindall = true;
                }
                if(isfindall) break;
            }
        }
        for(int i = 2;i<=2*n;i+=2){
            printf("%lld\n",x[i]);
        }
    }
    return 0;
}
posted @ 2017-08-09 22:23  pengwill  阅读(136)  评论(0编辑  收藏  举报