翻译:
你有两个正整数序列𝑎1,…,𝑎𝑛𝑏1,…,𝑏𝑚。对于每个𝑗= 1,…,𝑚找到的最大公约数𝑎1 +𝑏𝑗,…,𝑎𝑛+𝑏𝑗。
输入
第一行包含两个整数𝑛和𝑚(1≤𝑛,𝑚≤2⋅105)。
第二行包含𝑛整数𝑎1,…,𝑎𝑛(1≤𝑎𝑖≤1018)。
第三行包含𝑚整数𝑏1,…,𝑏𝑚(1≤𝑏𝑗≤1018)。
输出
打印𝑚个整数。他们应该等于GCD𝑗-th(𝑎1 +𝑏𝑗,…,𝑎𝑛+𝑏𝑗)。
例子
inputCopy
4个4
1 25 121 169
1 2 7 23
outputCopy
2 3 8 24
思路:经典gcd,b>a,gcd(a,b)=gcd(a,b-a)。
然后我们将A排序,然后对于所有最后的gcd,其实就是对于排过序,a[1]后边的减去a[1],最后再于a[1]+k取gcd,具体是因为 b>a,gcd(a,b)=gcd(a,b-a)。
代码:
/*Looking! The blitz loop this planet to search way
Only my RAILGUN can shoot it 今すぐ
身体中を 光の速さで
駆け巡った確かな予感
掴め! 望むものなら残さず
輝ける自分らしさで
信じてるよ あの日の誓いを
この瞳に光る涙それさえも 強さになるから
*/
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<tuple>
#include<numeric>
using namespace::std;
typedef long long ll;
inline __int128 read(){
__int128 x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if(ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(__int128 x){
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
int n,m;
ll q,w,e;
ll a[200005];
ll b[200005];
int main(){
ios::sync_with_stdio(false);
cin.tie(); cout.tie();
cin>>n>>m;
for (int i =1; i<=n; i++) {
cin>>a[i];
}
sort(a+1, a+1+n);
q=0;
for (int i =2; i<=n; i++) {
q=gcd(q,a[i]-a[1]);
}
for (int i =1; i<=m; i++) {
cin>>b[i];
}
for (int i =1; i<=m; i++) {
printf("%lld ",gcd(a[1]+b[i],q));
}printf("\n");
return 0;
}