CF1459-C. Row GCD
题意:
给出两个整数序列\(a、b\),他们的长度分别为\(n,m\)。对于数组\(b\)中的每个数字,让你求出\(gcd(a_1+b_j,a_2+b_j,...,a_n+b_j)\)。
思路:
本题用到了\(gcd\)的两个性质:
1. \(gcd(a_1,a_2,...,a_n) = gcd(a_1,gcd(a_2,..,a_n))\)
2. \(gcd(a_1,a_2,...,a_{n-1},a_n)=gcd(a_1,a_2-a_1,...,a_n-a_{n-1})\),其中\(a_1<=a_2<=...<=a_n\)
所以题中的式子\(gcd(a_1+b_j,a_2+b_j,...,a_n+b_j)=gcd(a_1+b_j,a_2-a_1,a_3-a_2,...,a_n-a_{n-1})\)。对于上面的式子,只需要先提前求\(gd=gcd(a_2-a_1,a_3-a_2,...,a_n-a_{n-1})\),然后对于每个\(b_j\)求出\(gcd(gd,a_1+b_j)\)就是答案。
AC代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
typedef long long ll;
const int Maxn = 200005;
ll a[Maxn], b[Maxn];
ll gcd(ll _a, ll _b) {
return !_b ? _a : gcd(_b, _a % _b);
}
void solve() {
int n, m;
scanf("%d %d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%lld", a + i);
}
for (int i = 0; i < m; i++) {
scanf("%lld", b + i);
}
std::sort(a, a + n);
ll gd = 0;
for (int i = 1; i < n; i++) {
gd = gcd(gd, a[i] - a[i - 1]);
}
for (int i = 0; i < m; i++) {
printf("%lld%c", gcd(gd, a[0] + b[i])," \n"[i == m - 1]);
}
}
int main() {
int T;
solve();
return 0;
}