2 solutions

  • 2
    @ 2025-5-9 17:13:10

    #include <bits/stdc++.h> using namespace std; #define ll long long

    // 计算最大公约数,处理0的情况 ll Gcd(ll x, ll y) { if (x == 0) return y; if (y == 0) return x; return __gcd(x, y); // 使用内置函数加速 }

    void solve() { ll n, k; cin >> n >> k; vector a(n + 1); // 原始数组 vector pre(n + 1, 0); // 前缀GCD数组 vector hou(n + 2, 0); // 后缀GCD数组

    // 输入并初始化前缀/后缀数组
    for (int i = 1; i <= n; i++) cin >> a[i];
    pre[1] = a[1];
    hou[n] = a[n];
    
    // 计算前缀GCD
    for (int i = 2; i <= n; i++)
        pre[i] = Gcd(pre[i - 1], a[i]);
    
    // 计算后缀GCD
    for (int i = n-1; i >= 1; i--)
        hou[i] = Gcd(hou[i + 1], a[i]);
    
    ll ans = pre[n]; // 初始答案为未修改的全局GCD
    
    // 遍历所有可能的修改左端点i
    for (int i = 1; i <= n; i++) {
        // 只有当当前位置i使得前缀GCD变化时才处理(剪枝优化)
        if (pre[i] != pre[i - 1]) {
            ll tem = pre[i - 1]; // 前i-1项的GCD
            
            // 枚举右端点j,将i到j区间+k后计算GCD
            for (int j = i; j <= n; j++) {
                tem = Gcd(tem, a[j] + k); // 累计修改后的GCD
                // 组合前缀i-1项的GCD、当前区间修改后的tem、后缀j+1项的GCD
                ans = max(ans, Gcd(tem, hou[j + 1]));
            }
        }
    }
    cout << ans << endl;
    

    }

    signed main() { int tcase = 1; while (tcase--) solve(); return 0; } 这是加了详细注释的代码,方便理解

    • -1
      @ 2025-5-6 21:50:34

      观察到aia_i最大101810^{18};前缀gcd最多log1018log10^{18}数量级,利用前缀gcdgcd跟后缀gcdgcd可以实现。

      只有前缀 gcd pre[i]!=pre[i+1]gcd \ pre[i]!=pre[i+1]的时候需要进行操作。

      #include <bits/stdc++.h>
      using namespace std;
      #define ll long long
      ll Gcd(ll x, ll y)
      {
          if (x == 0)
              return y;
          if (y == 0)
              return x;
          return __gcd(x, y);
      }
      void slove()
      {
          ll n, k;
          cin >> n >> k;
          vector<ll> a(n + 1);
          vector<ll> pre(n + 1, 0);
          vector<ll> hou(n + 2, 0);
          for (int i = 1; i <= n; i++)
          {
              cin >> a[i];
          }
          pre[1] = a[1];
          hou[n] = a[n];
          for (int i = 1; i <= n; i++)
          {
              pre[i] = Gcd(pre[i - 1], a[i]);
          }
          for (int i = n; i >= 1; i--)
          {
              hou[i] = Gcd(hou[i + 1], a[i]);
          }
          ll ans = pre[n];
          for (int i = 1; i <= n; i++)
          {
              if (pre[i] != pre[i - 1])
              {
                  ll tem = pre[i - 1];
                  for (int j = i; j <= n; j++)
                  {
                      tem = Gcd(tem, a[j] + k);
                      ans = max(ans, Gcd(tem, hou[j + 1]));
                  }
              }
          }
          cout << ans << endl;
      }
      signed main()
      {
      
          int tcase = 1;
          while (tcase--)
          {
              slove();
          }
          return 0;
      }
      
      • 1

      Information

      ID
      1469
      Time
      1000ms
      Memory
      256MiB
      Difficulty
      8
      Tags
      (None)
      # Submissions
      45
      Accepted
      7
      Uploaded By