一看就知道是扩展欧几里得,一用就废..
看了看别人的..
说下思路吧,
x2 = (a * x1 + b) % 10001;
x3 = (a * x2 + b) % 10001;
联立2个式子
x3 = (a * (a * x1 + b) % 10001 + b ) % 10001;
x3 = (a * (a * x1 + b) + b) % 10001;
所以x3+10001k= a * (a * x1 + b) % 10001 + b )
x3+10001k+10001k-b=a * (a * x1 + b)
最终:
x3+10001k=a * (a * x1 + b)+b;
(a+1)b -10001k=x3-a²x1
这不就是标准的欧几里得式吗,我们可以通过枚举a,然后算出一个是整数的b,
再通过检验这个b是否使得所有x[i]满足递推公式即可。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
void gcd(ull a,ull b,ull &d,ull &x,ull &y){
if(!b){d=a;x=1;y=0;return ;}
else{
gcd(b,a%b,d,y,x);
y-=(a/b)*x;
return ;
}
}
ull x[205];
int main(){
int t;
scanf("%d",&t);
for(int i=1;i<=2*t;i+=2)
scanf("%llu",&x[i]);
ull d,b,k;
ull value,a;
for(a=0;a<=10000;a++){
gcd(a+1,10001,d,b,k);
int ok=1;
value=x[3]-a*a*x[1];
if(value%d) continue;
b=b*value/d;
for(int i=2;i<=2*t;i++){
if(i&1){
if(x[i]!=((a*x[i-1]+b)%10001)){
ok=0;
break;
}
}
else
{
x[i]=(x[i-1]*a+b)%10001;
}
}
if(ok)
break;
}
for(int i=2;i<=2*t;i+=2)
printf("%llu\n",x[i]);
}