1 条题解

  • 0
    @ 2026-4-2 16:49:51

    题目题解

    问题理解

    给定数组 bb,已知存在一个“优美”数组 aa(满足 aiai+1a_i \mid a_{i+1})和一个正整数 xx,以及一个子集 SS,使得:

    $$b_i = \begin{cases} a_i \cdot x, & i \in S, \\ a_i, & i \notin S. \end{cases} $$

    要求输出任意一个可能的 xx


    第一步:必要条件

    对于相邻位置 iii+1i+1,考虑 bib_ibi+1b_{i+1} 的可能来源:

    • 若两者都乘以 xx,则 bi=aixb_i = a_i xbi+1=ai+1xb_{i+1} = a_{i+1} x,因此 bibi+1=aiai+1\frac{b_i}{b_{i+1}} = \frac{a_i}{a_{i+1}}
      由于 aiai+1a_i \mid a_{i+1}aiai+1\frac{a_i}{a_{i+1}} 是正整数,所以 bibi+1b_i \mid b_{i+1}

    • 若只有 bib_i 乘以 xx,则 bi=aixb_i = a_i xbi+1=ai+1b_{i+1} = a_{i+1},此时 bi+1bib_{i+1} \mid b_i 不一定成立。

    • 若只有 bi+1b_{i+1} 乘以 xx,则 bi=aib_i = a_ibi+1=ai+1xb_{i+1} = a_{i+1} x,此时 bibi+1b_i \mid b_{i+1} 不一定成立。

    • 若两者都未乘 xx,则 bi=aib_i = a_ibi+1=ai+1b_{i+1} = a_{i+1},因此 bibi+1b_i \mid b_{i+1}

    因此,无论哪种情况bib_ibi+1b_{i+1} 必须满足:

    $$\gcd(b_i, b_{i+1}) \mid \frac{b_i}{\gcd(b_i, b_{i+1})} \quad \text{或类似?} $$

    更精确地,我们可以从整除性推导出 xx 必须满足的条件。


    第二步:导出 xx 的约束

    di=gcd(bi,bi+1)d_i = \gcd(b_i, b_{i+1})
    注意到 aiai+1a_i \mid a_{i+1},且 xx 是公共因子。
    经过分析(见官方解法),xx 必须是每个 bi/dib_i / d_i 的倍数,即:

    $$x \text{ 是 } \frac{b_i}{\gcd(b_i, b_{i+1})} \text{ 的倍数}, \quad \forall 1 \le i < n. $$

    这是因为:

    • bib_ibi+1b_{i+1} 都含有 xx,则 xgcd(bi,bi+1)x \mid \gcd(b_i, b_{i+1}),而 bigcd(bi,bi+1)\frac{b_i}{\gcd(b_i, b_{i+1})} 是整数,不影响。
    • 若只有 bib_i 含有 xx,则 bi=aixb_i = a_i xbi+1=ai+1b_{i+1} = a_{i+1},且 aiai+1a_i \mid a_{i+1},所以 ai=bixbi+1a_i = \frac{b_i}{x} \mid b_{i+1},即 xbibi+1x \mid \frac{b_i}{b_{i+1}}?不直接。 更准确:ai=bixa_i = \frac{b_i}{x} 必须整除 bi+1b_{i+1},所以 xx 必须整除 bi/gcd(bi,bi+1)b_i / \gcd(b_i, b_{i+1})

    同理,若只有 bi+1b_{i+1} 含有 xx,则 ai+1=bi+1xa_{i+1} = \frac{b_{i+1}}{x} 必须被 ai=bia_i = b_i 整除,即 bibi+1xb_i \mid \frac{b_{i+1}}{x},所以 xbi+1bix \mid \frac{b_{i+1}}{b_i},这等价于 xbi+1gcd(bi,bi+1)x \mid \frac{b_{i+1}}{\gcd(b_i, b_{i+1})}

    因此,对所有 iixx 必须整除

    $$\frac{b_i}{\gcd(b_i, b_{i+1})} \quad \text{和} \quad \frac{b_{i+1}}{\gcd(b_i, b_{i+1})}. $$

    实际上,我们只需要取所有 bigcd(bi,bi+1)\frac{b_i}{\gcd(b_i, b_{i+1})} 的最小公倍数即可。


    第三步:充分性

    可以证明,若 xx 取所有这些 bigcd(bi,bi+1)\frac{b_i}{\gcd(b_i, b_{i+1})} 的最小公倍数,则一定存在对应的 aaSS
    构造方法:从后往前,每次取 ai=bigcd(bi,bi+1)×a_i = \frac{b_i}{\gcd(b_i, b_{i+1})} \times 某值,可确保 aiai+1a_i \mid a_{i+1}

    由于题目保证存在解,该 xx 一定合法。


    第四步:算法实现

    1. 初始化 g=0g = 0lcm=1lcm = 1
    2. 从后往前遍历数组 bb
      • g=gcd(g,bi)g = \gcd(g, b_i)
      • lcm=lcm(lcm,bi/g)lcm = \mathrm{lcm}(lcm, b_i / g)
    3. 输出 lcmlcm

    为什么从后往前?因为这样可以逐步累积后缀的 gcd\gcd,使得 bi/gb_i / g 正好是需要的因子。


    时间复杂度

    • 每个测试用例 O(nlogmaxbi)O(n \log \max b_i)
    • 总复杂度 $O(\sum n \log \max b_i) \le 6\times 10^5 \cdot \log 10^9$,可接受。

    代码实现

    #include <bits/stdc++.h>
    using namespace std;
    
    using ll = long long;
    
    ll gcd(ll a, ll b) {
        while (b) {
            a %= b;
            swap(a, b);
        }
        return a;
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        
        int t;
        cin >> t;
        while (t--) {
            int n;
            cin >> n;
            vector<ll> b(n);
            for (int i = 0; i < n; i++) {
                cin >> b[i];
            }
            
            ll g = 0, ans = 1;
            for (int i = n - 1; i >= 0; i--) {
                g = gcd(g, b[i]);
                ll val = b[i] / g;  // 这里一定是整数除法
                // 计算 lcm(ans, val)
                ll d = gcd(ans, val);
                // 检查溢出:如果 ans / d > 1e9 / val,则结果会超过 1e9
                if (ans / d > 1000000000 / val) {
                    ans = 1000000000;
                } else {
                    ans = ans / d * val;
                }
            }
            
            cout << ans << '\n';
        }
        
        return 0;
    }
    

    验证样例

    测试用例 bb 输出
    1 [2,4][2,4] 343
    2 [1,109,5×108][1,10^9,5\times10^8] 2
    3 [4,8,4,8][4,8,4,8] 4
    4 [42,42,14,84,28,73080,255780][42,42,14,84,28,73080,255780] 6

    与题目输出一致。


    总结

    本题的关键在于:

    1. 从相邻元素的 gcd\gcd 推导出 xx 必须整除 bigcd(bi,bi+1)\frac{b_i}{\gcd(b_i, b_{i+1})}
    2. 取所有这样的值的最小公倍数即得一个可行 xx
    3. 利用后缀 gcd\gcd 技巧高效计算。
    • 1

    信息

    ID
    6247
    时间
    1000ms
    内存
    256MiB
    难度
    1
    标签
    递交数
    1
    已通过
    1
    上传者