#691(Div。2)C。行GCD(最大公約数の性質)

タイトル説明

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 ba
したがって: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+バツAx c+バツbx d+バツcx
=gcd(a + x、b − a、c − b、d − c)gcd(a + x、ba、cb、dc)g c d a+x bA cb dc

だから答えが出てきます。
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 [ n1 ]

コードは以下のように表示されます
#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; 
}

おすすめ

転載: blog.csdn.net/li_wen_zhuo/article/details/113977816