UVA

来源:互联网 发布:电影语音翻译软件 编辑:程序博客网 时间:2024/06/05 10:22

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

题目大意:给出已知的x1,x3,x5,x7……x2k+1,找出a和b,满足递推式,并输出x2,x4,x6……x2k

解题思路:
枚举a,因为xi = (a*xi−1 + b) mod 10001,所以x3= (a*x2 + b) mod 10001,又因为x2= (a*x1 + b) mod 10001,所以x3= (a*( (a*x1 + b) mod 10001) + b) mod 10001=(a*( a*x1 + b) + b) mod 10001=a*a*x1+(a+1)*b mod 10001,所以x3+k*10001=a*a*x1+(a+1)*b转化为拓展欧几里得,由于k和b都必须是大于等于零,所以要把b从大于等于零的数开始枚举

AC代码:

#include<cstdio>#include<cmath>using namespace std;typedef long long LL;const int MAXN = 10000 + 5;const int MOD = 10001;int gt[MAXN], pt[MAXN];LL exgcd(LL a, LL b, LL &x, LL &y){    if (b == 0)    {        x = 1, y = 0;        return a;    }    LL d = exgcd(b, a%b, x, y);    LL tmp = x;    x = y;y = tmp - a / b*y;    return d;}void toSolve(int n){    for (LL a = 0;a <= 10000;a++)    {        LL x, y;        LL d = exgcd(a + 1, MOD, x, y);        LL c = gt[1] - a*a*gt[0];        if (c%d) continue;        x = c / d*x;y = -c / d*y;        int t, b = x;        if (c > 0)        {            t = abs(y / ((a + 1) / d));            if (y < 0)            {                if (y + (a + 1) / d*t < 0)                    t++;                b = x + 10001 / d*t;            }            else if (y > 0)                b = x - 10001 / d*t;        }        else        {            t = abs(x / (10001 / d));            if (x < 0)            {                if (x + 10001 / d*t < 0)                    t++;                b = x + 10001 / d*t;            }            else if (x > 0)                b = x - 10001 / d*t;        }        while (b <= 10000)        {            bool flag = 1;            for (int i = 0;i < n;i++)            {                pt[i] = (gt[i] * a + b) % MOD;                if (i < n - 1 && (a*pt[i] + b) % MOD != gt[i + 1])                {                    flag = 0;                    break;                }            }            if (flag) return;            b += 10001 / d;        }    }    //x += 10001 / d;    //y += (a + 1) / d;}int main(){    int n;scanf("%d", &n);    for (int i = 0;i < n;i++)        scanf("%d", gt + i);    toSolve(n);    for (int i = 0;i < n;i++)        printf("%d\n", pt[i]);    return 0;}