CF1459-C. Row GCD

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;
}

posted @ 2021-01-24 19:23  牟翔宇  阅读(116)  评论(0编辑  收藏  举报