詳細説明#C. 複数の数値の gcd

トピック


アイデア 1

質問の意味を直接シミュレートし、変更された数値を列挙して変更し、それらの最大公約数を計算し、最大値を取るというものです。

時間計算量: O(n * n * log(n))、タイムアウトになります

あまりにも単純なので、このアイデアのコードはここでは示しません。


アイデア 2

この質問では、時間の複雑さを軽減するために前処理が必要です。

アイデアは、配列を走査し、gcd(a[1],a[2]...a[i])の結果をb[i]に格納することです。

次に、配列を逆方向に走査し、 gcd(a[n],a[n - 1]...a[n - i + 1]) の結果をc[n - i + 1]に格納します。

次に、変更する数値 a[i]を列挙し、ans としてgcd(b[i - 1], c[i + 1]) を取得します。

原則: いくつかの数値の gcd 結果はそれらの最小値以下でなければならないため、a[i] から >b[i - 1]、c[i + 1] およびそれらの倍数に変更された数値が最適になります。 gcd で a[i] に変更された数値 (a[i]、b[i - 1]、c[i + 1] によって変更された数値) は結果に影響を与えないため、gcd(b [ i - 1 ] 、c[i + 1]


コード

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[10000001],b[10000001],c[10000001],s,ans;
signed main()
{
  cin>>n;
  for(int i = 1;i <= n;i++) cin>>a[i];
  for(int i = 1;i <= n;i++)
  {
      s = __gcd(s,a[i]);
      b[i] = s;
  }
  s = 0;
  for(int i = n;i > 0;i--)
  {
      s = __gcd(s,a[i]);
      c[i] = s;
  }
  for(int i = 1;i <= n;i++)
  {
      int ta = b[i - 1],tb = c[i + 1],tc = __gcd(ta,tb);
      ans = max(ans,tc);
  }
  cout<<ans;
  return 0;
}

おすすめ

転載: blog.csdn.net/weq2011/article/details/128773383
おすすめ