版权声明:希望能在自己成长的道路上帮到更多的人,欢迎各位评论交流 https://blog.csdn.net/yiqzq/article/details/82156012
原题地址:here
题意:有 个整数 满足递推式 。由这个递推式计算出了长度为 的数列,现在要求输入 , 输出 如果有多种可能的输出,任意输出一个结果即可。
思路:因为题目中
的数据范围只有
,所以我们可以通过枚举
去确定
,那么如何去求
呢?
我们可以通过扩展欧几里得算法去求解线性同余方程.
#include <bits/stdc++.h>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)+1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 1e5 + 5;
const int mod = 10001;
ll x, y;
ll d1[maxn];
ll d2[maxn];
int n;
ll exgcd(ll a, ll b, ll &x, ll &y) { //求解ax+by=gcd(a,b)
if (b == 0) {
x = 1;
y = 0;
return a;
}
ll ans = exgcd(b, a % b, x, y);
ll temp = x;
x = y;
y = temp - (a / b) * y;
return ans;
}
bool check(ll a, ll b) {
for (int i = 1; i <= n; i++) {
d2[i] = (d1[i] * a + b)%mod;
if (i != n) {
if (d1[i + 1] != (a * d2[i] + b) % mod) return 0;
}
}
return 1;
}
int main() {
while (~scanf("%d", &n)) {
int f = 0;
for (int i = 1; i <= n; i++) {
scanf("%lld", &d1[i]);
}
for (ll i = 0; i <= 10000; i++) {//枚举a
ll gcd = exgcd((i + 1), 10001, x, y);
ll sum = d1[2] - i * i * d1[1];//注意这里会爆int,因此要开long long
if (sum % gcd) continue;
ll b = x * sum / gcd;
f = check(i, b);
if (f) break;
}
for (int i = 1; i <= n; i++) printf("%lld\n", d2[i]);
}
return 0;
}