当前位置:   article > 正文

A. Row GCD(更相减损术+gcd的性质)

a. row gcd

Problem - 1458A - Codeforces

 

给你两个正整数序列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] 计算即可

 

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<string>
  5. #include<map>
  6. #include<vector>
  7. #include<queue>
  8. using namespace std;
  9. #define int long long
  10. int a[200505];
  11. int b[200050];
  12. void solve()
  13. {
  14. int n,m;
  15. cin >> n >> m;
  16. for(int i = 1;i <= n;i++)
  17. cin >> a[i];
  18. for(int i = 1;i <= m;i++)
  19. cin >> b[i];
  20. int ma = 0;
  21. for(int i = 2;i <= n;i++)
  22. {
  23. ma = __gcd(ma,abs(a[i]-a[1]));
  24. }
  25. for(int i = 1;i <= m;i++)
  26. {
  27. int x = a[1] + b[i];
  28. cout<<__gcd(ma,x)<<" ";
  29. }
  30. cout<<"\n";
  31. }
  32. signed main()
  33. {
  34. int t = 1;
  35. // cin >> t;
  36. while(t--)
  37. {
  38. solve();
  39. }
  40. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/75450
推荐阅读
相关标签
  

闽ICP备14008679号