You are given two positive integer sequences a1,…,an and b1,…,bm. For each j=1,…,m find the greatest common divisor of a1+bj,…,an+bj.
Input
The first line contains two integers n and m (1≤n,m≤2⋅105).
The second line contains n integers a1,…,an (1≤ai≤1018).
The third line contains m integers b1,…,bm (1≤bj≤1018).
Output
Print m integers. The j-th of them should be equal to GCD(a1+bj,…,an+bj).
Example
input
4 4
1 25 121 169
1 2 7 23
output
2 3 8 24
题意:题目中有m次询问,每次要求出n个数加上一个数之后,这n个数的gcd。
分析:此题用到了gcd的更相减损术。gcd(a,b)=gcd(a,b−a);gcd(a,b,c) = gcd(a,b-a,c-b)那么推广到这个数组,gcd(a1+bj,…,an+bj)=gcd(a1+bj,a2-a1,a3-a2,…,an-a(n-1))。所以我们只需先求出g=gcd(a2-a1,a3-a2,…)。而最终答案就是gcd(g,a1+bj);
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
long long int a[200005],b[200005];
long long int c[200005];
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m)){
for(int i=0;i<n;i++){
scanf("%lld",&a[i]);
if(i==0)continue;
c[i]=a[i]-a[i-1];
}
long long int ans=c[1];
for(int i=1;i<n;i++)ans=__gcd(ans,c[i]);
for(int j=0;j<m;j++){
scanf("%lld",&b[j]);
cout<<abs(__gcd(ans,b[j]+a[0]))<<" ";
}
cout<<endl;
}
return 0;
}
相关题目
也是与gcd更相减损有关的题
GCD更相减损术算法解析

本文介绍了一个利用更相减损术求解多个数的最大公约数(GCD)的问题。通过分析给出的两个整数序列,文章提供了一种高效算法来计算每个序列元素加固定数后的最大公约数。
533

被折叠的 条评论
为什么被折叠?



