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

题目链接 https://cn.vjudge.net/problem/UVA-12169

【题意】
有一个长度为T的整数序列x,已知x[i]=(a*x[i]-1+b) mod 10001,且告诉你x[1],x[3]………x[2*T-1],让你求出其偶数项分别是多少,输出任意解即可

【思路】
因为取模的范围不大,所以可以枚举a(0~10000),然后根据x[1],x[3]计算出b,然后再去验证(a,b)对整个序列是否成立
x[2] = (a*x[1]+b)% 10001
x[3] = (a*x[2]+b)% 10001
联立上面两式,可得
x[3]=(a* (a*x[1]+b)%10001 +b) % 10001
即 x[3]=(a* (a*x[1]+b)+b) % 10001
即 x[3]=(a*a*x[1]+(a+1)*b) % 10001
也就是说(a+1)*b-10001k=x[3]-a*a*x1(k为整数)
只有b,k为未知量,这样就转换成了求解ax+by=c的整数解问题了,用扩展欧几里得计算

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=220;

void gcd(ll a,ll b,ll& d,ll& x,ll& y){
    if(0==b){d=a;x=1;y=0;}
    else {gcd(b,a%b,d,y,x);y-=x*(a/b);}
}

int n;
ll f[maxn];

int main(){
    scanf("%d",&n);
    for(int i=1;i<=2*n;i+=2) scanf("%lld",&f[i]);
    for(ll a=0;a<10001;++a){
        ll d,b,k,c=f[3]-a*a*f[1];
        gcd(a+1,-10001,d,b,k);
        if(c%d) continue;
        b*=c/d;
        bool ok=true;
        for(int i=2;i<=2*n;++i){
            ll tmp=(a*f[i-1]+b)%10001;
            if((i&1) && tmp!=f[i]){ok=false;break;}
            f[i]=tmp;
        }
        if(ok){
            for(int i=2;i<=2*n;i+=2){
                printf("%lld\n",f[i]);
            }
            break;
        }
    }
    return 0;
}
posted @ 2018-08-21 14:27  不想吃WA的咸鱼  阅读(98)  评论(0编辑  收藏  举报