タイトル説明
2つの正の整数シーケンスa1、…、anとb1、…、bmが与えられます。各j = 1、…、mについて、a1 + bj、…、an + bjの最大公約数を見つけます。
入力
最初の行には、2つの整数nとm(1≤n、m≤2・105)が含まれています。
2行目には、n個の整数a1、…、an(1≤ai≤1018)が含まれています。
3行目には、m個の整数b1、…、bm(1≤bj≤1018)が含まれています。
出力
m個の整数を出力します。それらのj番目はGCD(a1 + bj、…、an + bj)と等しくなければなりません。
例
入力
4 4
1 25 121 169
1 2 7 23
出力
2 3 8~24
一般的なアイデア
n個の数a []とm個の数b []を与えます。尋ねるGCDを(B [I] + [1]、B [I] + [2]、...、B [I] + [N])GCD(B [I] + [1]、B [ i] + a [2]、……、b [i] + a [n])g c d (b [ i ]+a [ 1 ] 、b [ i ]+a [ 2 ] 、……、b [ i ]+a [ n ] )的值(1 <= i <= m)。
トピック分析
gcd(a、b)= gcd(a、b − a)gcd(a、b)= gcd(a、ba)であることがわかっていますg c d (a 、b )=g c d (a 、b−a )。
したがって:gcd(a + x、b + x、c + x、d + x)gcd(a + x、b + x、c + x、d + x)g c d (a+x 、b+x 、c+x 、d+x )
=gcd(a + x、b + x − a − x、c + x − b − x、d + x − c − x)gcd(a + x、b + xax、c + xbx、d + xcx )g c d (a+x 、b+バツ−A−x 、c+バツ−b−x 、d+バツ−c−x )
=gcd(a + x、b − a、c − b、d − c)gcd(a + x、ba、cb、dc)g c d (a+x 、b−A 、c−b 、d−c )
だから答えが出てきます。
gcd(b [i] + a [1]、b [i] + a [2]、……、b [i] + a [n])gcd(b [i] + a [1]、b [i ] + a [2]、……、b [i] + a [n])g c d (b [ i ]+a [ 1 ] 、b [ i ]+a [ 2 ] 、……、b [ i ]+a [ n ] )
=gcd(b [i] + a [1]、a [2] − a [1]、……、a [n] − a [n − 1])gcd(b [i] + a [1]、a [2] -a [1]、……、a [n] -a [n-1])g c d (b [ i ]+a [ 1 ] 、a [ 2 ]−a [ 1 ] 、……、a [ n ]−a [ n−1 ] )
コードは以下のように表示されます
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
#include <unordered_map>
#include <queue>
#include <vector>
#include <set>
#include <bitset>
#include <algorithm>
#define LL long long
#define PII pair<int,int>
#define x first
#define y second
using namespace std;
const int N=2e5+5,mod=1e9+7;
LL a[N],b[N];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=m;i++) scanf("%lld",&b[i]);
LL res=0;
for(int i=2;i<=n;i++) res=__gcd(res,a[i]-a[i-1]);
for(int i=1;i<=m;i++)
{
LL ans=__gcd(res,a[1]+b[i]);
printf("%lld ",abs(ans));
}
return 0;
}