您的位置:首页 > 其它

Uva 12169 Disgruntled Judge 扩展欧几里得,暴力

2015-09-15 11:38 525 查看
Once upon a time, there was an NWERC judge with a tendency to create slightly too hard problems. As a result, his problems were never solved. As you can image, this made our judge somewhat frustrated.This year, this frustration has culminated, and he has
decided that rather than spending a lot of time constructing a well-crafted problem, he will simply write some insanely hard problem statement and just generate some random input and output les. After all, why bother having proper test data if nobody is going
to try the problem anyway?Thus, the judge generates a test case by simply letting the input be a random number, and letting the output be another random number. Formally, to generate the data set with T test cases, the judge generates 2T random numbers x1,
. . . , x2T between 0 and 10 000, and then writes T, followed by the sequence x1, x3, x5, . . . , x2T −1 to the input le, and the sequence x2, x4, x6, . . . , x2T to the output le.The random number 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 that such a poorly designed problem would not be used in a contest of such high standards as NWERC. Well, you were wrong.

Input

On the r-st line one positive number: the number of test cases, at most 100. After that per test case:

• One line containing an integer n (0 ≤ n ≤ 10000): an input test case.The input le is guaranteed to be generated by the process described above.

Output

Per testcase: • One line with an integer giving the answer for the test case.If there is more than one output le consistent with the input le, any one of these is acceptable.

Sample Input

3

17

822

3014

Sample Output

9727

1918

4110

给出一个规模T,取定a,b,x1,将按照递推公式 xi=(a*xi-1+b)mod 10001 来求解x2,x3...直到x2T 现在,只知道 x1,x3,x5...x2T-1,试求x2,x4...x2T

a与b是不知道的,但是我们发现,所有数值都是对10001取模所得,这意味着他们均小于10001,因此,如果能给出这样一个长为2T的序列,a值一定可以限制在10000以内。

如果a值给定了,b是可以求出来的,这就用到了扩展欧几里得

转化为扩展欧几里得的过程如下:

假定a已知,我们知道 x2=(x1*a+b)% mod

又有 x3=(x2*a+b)%mod = (((x1*a+b)%mod)*a+b)%mod = (x1*a*a+(a+1)*b)%mod

故,x1*a*a+(a+1)b=x3+k*mod

注意到我们要求的是b,而k也是未知的,因此可以转化为求他俩的不定方程

x1*a*a-x3=(a+1)*b-k*mod

这就相当于对于a+1和mod 求b与k满足上式,就是扩展欧几里得的一个应用了,这里的进一步说明参见另一篇博文hdu 1573

假设一个a值(10000以内),并根据x1 x3求出b,利用递推公式求接下来的每一项,如果这组ab 值求出来的某一个奇数项与测试数据中给出的不一致,说明这个假设的a值是错误的,则继续试验下一个a值,这样最多试验10000次,最坏的情况下复杂度为 O(10000*(sigma(lga)+2T))...好吧这是我瞎写的。。不知道对不对。复杂度并不高

代码0MS通过

code:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
#include<vector>
#include<string>
#include<cmath>
#include<stack>
//#define file
#define maxn 100010
#define inf 0x3f3f3f3f
#define LL long long
using namespace std;
long long mod=10001;
int t;
long long ans[220];
void ex_eucild(LL a,LL b,LL& d,LL& x,LL& y)
{
if(!b)
{
d=a;
x=1;
y=0;
}
else
{
ex_eucild(b,a%b,d,y,x);
y-=x*(a/b);
}
}
int main()
{
scanf("%d",&t);
long long a,d,k,b;
for(int i=1; i<=2*t; i+=2)
{
scanf("%lld",&ans[i]);
}
for(a=0; a<=10000; a++)
{
long long tp=ans[3]-a*a*ans[1];
ex_eucild(mod,a+1,d,k,b);
if(tp%d)continue;
b=b*tp/d;
bool flag=true;
for(int i=2;i<=2*t;i++)
{
if(i%2)
{
if(ans[i]!=(ans[i-1]*a+b)%mod)
{
flag=false;
break;
}
}
else
{
ans[i]=(ans[i-1]*a+b)%mod;
}
}
if(flag)break;
}
for(int i=2;i<=2*t;i+=2)
{
printf("%lld\n",ans[i]);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: