トピック
アイデア 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;
}