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

来源:互联网 发布:sqlserver select if 编辑:程序博客网 时间:2024/04/27 15:29

                                    Disgruntled Judge

          Once upon atime, there was an NWERC judge with a tendency to create slightly too hardproblems. As a result, his problems were never solved. As you can image, thismade our judge somewhat frustrated. This year, this frustration has culminated,and he has decided that rather than spending a lot of time constructing awell-crafted problem, he will simply write some insanely hard problem statementand just generate some random input and output les. After all, why botherhaving proper test data if nobody is going to try the problem anyway?

         Thus, the judge generates a testcase by simply letting the input bea random number, and letting the output be another random number. Formally, togenerate the data set with T test cases, the judge generates 2T random numbersx1, . . . , x2T between 0 and 10 000, and then writes T, followed by thesequence x1, x3, x5, . . . , x2T −1 to the input le, and the sequence x2, x4,x6, . . . , x2T to the output le.

         The randomnumber generator the judge uses is quite simple. He picks three numbers x1, a,and b between 0 and 10 000 (inclusive), and then for i from 2 to 2T lets xi =(a · xi−1 + b) mod 10001.  

        You may have thought thatsuch a poorly designed problem would not be used in a contest of such highstandards as NWERC. Well, you were wrong.

Input

 On the rst line one positivenumber: the number of testcases, at most 100. After that per testcase:

• One linecontaining an integer n (0 ≤ n ≤ 10000): an input testcase.

The input le isguaranteed to be generated by the process described above.

Output

Per testcase:

• One line withan integer giving the answer for the testcase.

If there is morethan one output le consistent with the input le, any one of these isacceptable.

Sample Input

 3

17

822

3014

Sample Output

9727

1918

4110

题意:输入一个随机数,输出一个随机数,找来三个整数x1,a,d,按递推公式xi = (axi-1 + b) mod 10001,计算出长度为2T的数列,其中T是测试数据的个数。然后把T和x1,x3.........x2T-1写入输入文件,x2,x4......x2T写入输出文件 。你的任务是:输入T,x1,x3.........x2T-1  ,  输出x2,x4......x2T。输入保证T<=100,且输入的所有值为0~10000的整数。如有多种可能,任意输出一种即可;

分析:知道a就可通过扩展欧几里得x3 = (ax2 + b) mod 10001,由于式子对10001取模得知 a是0~10000的整数,枚举所有10000,求b看是否符合条件

由 x3 = (ax2 + b) mod 10001得

x2 = (ax1 + b)mod10001

x3 = (a^2x1+ab+b) mod 10001

x3 = (((a+1)b) + a^2x1)mod 10001

(a+1)b + 10001k = x3 - a^2x1

设gd为a+1 和 10001 的最大公约数

(a+1) b*gd/( x3 - a^2x1) + 10001k*gd/( x3 - a^2x1) = d;

令 x = b*gd/( x3 - a^2x1),  y =  k*gd/( x3 - a^2x1);

必须确保  gd/( x3 - a^2x1) 为整数 

代码:

#include<stdio.h>#include<string.h>typedef long long LL;int exc_gcd(int a, int b, int &x,int &y){    if(b==0)    {        x = 1;        y = 0;        return a;    }    int GCD = exc_gcd(b,a%b,x,y);    int tmp = x;    x = y;    y = tmp-(a/b)*y;    return GCD;}int main(){    int d[220];    int n;    while(~scanf("%d",&n))    {        int i;        for(i = 0; i < n; i ++)            scanf("%d",&d[(i<<1)+1]);        d[2] = d[1];        LL a,b;        int gd,x,y;        if(n>=2)        {            for(a = 0; a <= 10000; a ++)            {                gd = exc_gcd(a+1,10001,x,y);                if((d[3]-a*a*d[1])%gd==0)                {                    b = x*((d[3]-a*a*d[1])/gd);                    for(i = 1; i <= n; i ++)                    {                        d[i<<1] = (d[(i<<1)-1]*a + b)% 10001;                        if(d[(i<<1)+1]!=(d[i<<1]*a + b)% 10001)                            break;                    }                    if(i==n)                        break;                }            }        }        for(i = 1; i <= n; i ++)            printf("%d\n",d[i<<1]);    }    return 0;}