赞
踩
给你两个正整数序列a1,...,an和b1,...,bm。对于每个j=1,...,m,求a1+bj,...,an+bj的最大公除数。
输入
第一行包含两个整数n和m(1≤n,m≤2⋅105)。
第二行包含n个整数a1,...,an(1≤ai≤1018)。
第三行包含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,m的范围肯定不能暴力,
既然他让我们求最大公因数,我们想想其性质
1.gcd(a,b) = gcd(a,b-a)
2.gcd(a,b,c) = gcd(a,gcd(b,c)
结合a1+bj,...,an+bj,
我们从这两条性质入手,
我们考虑一下第一条性质
gcd(a1+bj,a2 + bj) = gcd(a1+bj,a2 - a1)
考虑第二条性质,是不每个i= 2~n都可以转化为 ai - a1
我们只需要先得到gcd(ai-a1,....an-a1) i~n
再对a[1] + b[1~j] 计算即可
- #include<iostream>
- #include<algorithm>
- #include<cstring>
- #include<string>
- #include<map>
- #include<vector>
- #include<queue>
- using namespace std;
- #define int long long
- int a[200505];
- int b[200050];
- void solve()
- {
- int n,m;
- cin >> n >> m;
- for(int i = 1;i <= n;i++)
- cin >> a[i];
- for(int i = 1;i <= m;i++)
- cin >> b[i];
- int ma = 0;
- for(int i = 2;i <= n;i++)
- {
- ma = __gcd(ma,abs(a[i]-a[1]));
- }
- for(int i = 1;i <= m;i++)
- {
- int x = a[1] + b[i];
- cout<<__gcd(ma,x)<<" ";
- }
- cout<<"\n";
- }
- signed main()
- {
- int t = 1;
- // cin >> t;
- while(t--)
- {
- solve();
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。