问题
分析
这道题直接暴力就可以了,但总觉得如果数据多的话会超时
#include <cstring>
#include <cstdio>
const int maxn=10000+1;
int x[300],T;
int main(void){
scanf("%d",&T);
for(int i=1;i<(T<<1);i+=2){
scanf("%d",&x[i]);
}
int ok=1;
for(int a=0;a<maxn;++a){
for(int b=0;b<maxn;++b){
ok=1;
for(int i=2;i<=(T<<1);++i){
if((i&1)==0) x[i]=(a*x[i-1]+b)%maxn;
else if(x[i]!=(a*x[i-1]+b)%maxn){
ok=0;
break;
}
}
if(ok==1){
for(int i=2;i<=(T<<1);i+=2) printf("%d\n",x[i]);
break;
}
}
}
return 0;
}
还有一种解方程的做法,枚举a,求解 x 3 ≡ ( a 2 x 1 + a b + b ) m o d M x_3 \equiv (a^2x_1+ab+b)mod\space M x3≡(a2x1+ab+b)mod M,其中x1,x3已知,经过变换得到 ( a + 1 ) b − k M = x 3 − a 2 x 1 , k (a+1)b-kM=x_3-a^2x_1,k (a+1)b−kM=x3−a2x1,k是除法得到的倍数
#include <cstring>
#include <cstdio>
typedef long long ll;
const ll maxn=10000+1;
ll x[300],T;
ll exGCD(ll a,ll b,ll &x,ll &y){
if(!b){
x=1;
y=0;
return a;
}
ll ans=exGCD(b,a%b,y,x);
y=y-a/b*x;
return ans;
}
int main(void){
scanf("%d",&T);
for(int i=1;i<(T<<1);i+=2){
scanf("%d",&x[i]);
}
ll ok=1;
for(long long a=0;a<maxn;++a){ //枚举a
ll c=x[3]-a*a*x[1];
ll b,k,ok=1;
ll gcd=exGCD(a+1,maxn,b,k);
if(c%gcd) continue; //如果c不是gcd的倍数,那么无解
b=c/gcd*b;
for(ll i=2;i<=(T<<1);++i){ //检测整个序列是否符合
if((i&1)==0) x[i]=(a*x[i-1]+b)%maxn;
else if(x[i]!=(a*x[i-1]+b)%maxn){
ok=0;
break;
}
}
if(ok==1){
for(ll i=2;i<=(T<<1);i+=2) printf("%lld\n",x[i]);
break;
}
}
return 0;
}