1. 程式人生 > 實用技巧 >Codeforces Round #691 (Div. 2) C. Row GCD (數學)

Codeforces Round #691 (Div. 2) C. Row GCD (數學)

  • 題意:給你兩個陣列\(a\)\(b\),對於\(j=1,...,m\),找出\(a_1+b_j,...,a_n+b_j\)\(gcd\).
  • 題解:我們很容易的得出\(gcd\)的一個性質:\(gcd(a,b)=gcd(a,b-a),gcd(a,b,c)=gcd(a,b-a,c-b)\)以此往後類推, 那麼對於此題,我們要求\(gcd((a_1+b_j),(a_2+b_j),...,(a_n+b_j))=gcd(a_1+b_j,a_2-a_1,...,a_{n}-a_{n-1})\).所以我們可以先對\(a\)的差分陣列求\(gcd\),然後再對每個\(b_j\)\(gcd(a_1+b_j,gcd(d))\)
    即可.
  • 程式碼:
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
#define rep(a,b,c) for(int a=b;a<=c;++a)
#define per(a,b,c) for(int a=b;a>=c;--a)
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}

int n,m;
ll a[N],b[N];
ll d[N];

int main() {
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>m;

	rep(i,1,n) cin>>a[i];
	rep(i,1,m) cin>>b[i];

	sort(a+1,a+1+n);

	rep(i,1,n) d[i]=a[i]-a[i-1];

	ll res=d[2];

	rep(i,2,n) res=gcd(res,d[i]);

	rep(i,1,m){
		cout<<gcd(res,d[1]+b[i])<<' ';
	}


    return 0;
}