题目链接
题意
给出一个序列的一半,x1,x3,x5,x7,…x(2*t-1),序列的长度为2 * t。这个序列是通过x[i] = (x[i-1] * a + b) % mod (mod == 10001) 生成的。要求让你输出x2,x4,x6….,x(2 * t)
其中t <=100。输入的x[i],a,b都是0~10000的整数。
题解
根据紫书的思路
由于a,b都是0~10000的整数,可以枚举a。
表示出x2 = (x1 * a+b)%mod,x3=(x2 * a+b)%mod。
于是得到x3 = (a * a * x1 + a * b + b) % mod
于是得到 x3 - a * a * x1 = k * mod + b * (a+1)
再通过扩展欧几里得求得b。用a,b去验证序列是否合法即可。
注意序列用 long long
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 210;
const int mod = 10001;
ll arr[maxn];
ll exgcd(ll a,ll b,ll &x,ll &y) {
if(b == 0) {
x = 1,y = 0;
return a;
}
ll r = exgcd(b,a%b,y,x);
y -= a/b*x;
return r;
}
int main()
{
int t;
scanf("%d",&t);
for(int i = 1;i<2*t;i+=2) scanf("%lld",&arr[i]);
for(ll a=0;a<=10000;a++)
{
ll c = arr[3] - a * a * arr[1];
ll aa = a + 1;
ll bb = mod;
ll x,y;
ll gcd = exgcd(aa,bb,x,y);
if(c % gcd) continue;
x *= (c / gcd);
ll M = mod / gcd;
x = (x % M + M) % M;
bool ans = true;
for(int i=2;i<=2*t;i+=2)
{
arr[i] = (arr[i-1] * a + x ) % mod;
if(i!=2*t && arr[i+1] != (arr[i]*a+x)%mod) {ans = false;break;}
}
if(ans) {
for(int i=2;i<=2*t;i+=2) printf("%lld\n",arr[i]);
break;
}
}
return 0;
}