Problem p03061 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <utility>
#include <vector>
using namespace std;
#define ll long long
const double EPS = 1e-10;
const ll MOD = 7 + (1e+9);

const ll INF = 1e18 + 7;
#define all(v) v.begin(), v.end()
#define repi(i, m, n) for (ll i = m; i < n; i++)
#define rep(i, n) repi(i, 0, n)
typedef pair<ll, ll> P;
#define fi first
#define se second

// Range Minimum(Maximum) Query (RMQ)
// Big Range Query
// セグメント木 P(x, y) = P(値, 要素番号)
// インデックス取得したい場合: seg.update(k, k)
class SegmentTree {
public:
  ll n = 1;
  vector<P> seg[1]; // 0:最大	1:最小
  void init(ll N) { // N要素のセグメントツリー作成
    while (n < N)
      n *= 2;
    rep(i, 1) seg[i].resize(2 * n);
    fill(all(seg[0]), P(-1, -1));
  }
  ll gcd(ll a, ll b) {
    if (a == -1)
      return b;
    if (b == -1)
      return a;
    if (b == 0) {
      return a;
    } else {
      return gcd(b, a % b);
    }
  }
  P cmp_gcd(P x, P y) { // 比較関数
    P zz;
    zz.fi = gcd(x.fi, y.fi);
    zz.se = x.se;
    return zz;
  }
  void update(ll k, ll x, bool flag = false) { // kの値をxに変更
    k += n - 1;
    seg[0][k] = P(x, k - (n - 1));
    if (flag) {
      seg[0][k] = P(-1, -1);
    }
    while (k > 0) {
      k = (k - 1) / 2;
      seg[0][k] = cmp_gcd(seg[0][k * 2 + 1], seg[0][k * 2 + 2]);
    }
  }
  P calc(ll a, ll b, ll k, ll l, ll r, ll f) {
    if (b <= l || r <= a)
      return P(-1, -1);
    if (a <= l && r <= b)
      return seg[f][k];
    P vl = calc(a, b, k * 2 + 1, l, (l + r) / 2, f);
    P vr = calc(a, b, k * 2 + 2, (l + r) / 2, r, f);
    return cmp_gcd(vl, vr);
  }
  void erase(ll k) { update(k, -1, true); }
  ll get_gcd(ll a, ll b) { return calc(a, b, 0, 0, n, 0).fi; }
};

int main() {
  SegmentTree st;
  ll nn;
  cin >> nn;
  ll ans = 0;
  vector<ll> v(nn, 0);
  for (ll i = 0; i < nn; i++) {
    cin >> v[i];
  }
  st.init(nn);
  for (ll i = 0; i < nn; i++) {
    st.update(i, v[i]);
  }

  for (ll i = 0; i < nn; i++) {
    SegmentTree seg = st;
    seg.update(i, -1);
    // ans=max(ans,seg.get_gcd(0,nn));
    ans = max(ans, seg.seg[0][0].fi);
  }
  cout << ans << endl;
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <utility>
#include <vector>
using namespace std;
#define ll long long
const double EPS = 1e-10;
const ll MOD = 7 + (1e+9);

const ll INF = 1e18 + 7;
#define all(v) v.begin(), v.end()
#define repi(i, m, n) for (ll i = m; i < n; i++)
#define rep(i, n) repi(i, 0, n)
typedef pair<ll, ll> P;
#define fi first
#define se second

// Range Minimum(Maximum) Query (RMQ)
// Big Range Query
// セグメント木 P(x, y) = P(値, 要素番号)
// インデックス取得したい場合: seg.update(k, k)
class SegmentTree {
public:
  ll n = 1;
  vector<P> seg[1]; // 0:最大	1:最小
  void init(ll N) { // N要素のセグメントツリー作成
    while (n < N)
      n *= 2;
    rep(i, 1) seg[i].resize(2 * n);
    fill(all(seg[0]), P(-1, -1));
  }
  ll gcd(ll a, ll b) {
    if (a == -1)
      return b;
    if (b == -1)
      return a;
    if (b == 0) {
      return a;
    } else {
      return gcd(b, a % b);
    }
  }
  P cmp_gcd(P x, P y) { // 比較関数
    P zz;
    zz.fi = gcd(x.fi, y.fi);
    zz.se = x.se;
    return zz;
  }
  void update(ll k, ll x, bool flag = false) { // kの値をxに変更
    k += n - 1;
    seg[0][k] = P(x, k - (n - 1));
    if (flag) {
      seg[0][k] = P(-1, -1);
    }
    while (k > 0) {
      k = (k - 1) / 2;
      seg[0][k] = cmp_gcd(seg[0][k * 2 + 1], seg[0][k * 2 + 2]);
    }
  }
  P calc(ll a, ll b, ll k, ll l, ll r, ll f) {
    if (b <= l || r <= a)
      return P(-1, -1);
    if (a <= l && r <= b)
      return seg[f][k];
    P vl = calc(a, b, k * 2 + 1, l, (l + r) / 2, f);
    P vr = calc(a, b, k * 2 + 2, (l + r) / 2, r, f);
    return cmp_gcd(vl, vr);
  }
  void erase(ll k) { update(k, -1, true); }
  ll get_gcd(ll a, ll b) { return calc(a, b, 0, 0, n, 0).fi; }
};

int main() {
  SegmentTree st;
  ll nn;
  cin >> nn;
  ll ans = 0;
  vector<ll> v(nn, 0);
  for (ll i = 0; i < nn; i++) {
    cin >> v[i];
  }
  st.init(nn);
  for (ll i = 0; i < nn; i++) {
    st.update(i, v[i]);
  }

  for (ll i = 0; i < nn; i++) {
    st.update(i, -1);
    ans = max(ans, st.seg[0][0].fi);
    st.update(i, v[i]);
  }
  cout << ans << endl;
}