首页 > 其他分享 >[ARC126C] Maximize GCD 题解

[ARC126C] Maximize GCD 题解

时间:2023-08-14 19:25:18浏览次数:42  
标签:std GCD 题解 valueType ARC126C pos iter max sum

题意

给定一个序列 \(A\),每次操作可以使 \(A_i + 1\)(\(i \in \left[1, n\right]\),\(K\) 次操作的 \(i\) 可以不同),最多可以做 \(K\) 次。问 \(\gcd{A_1, A_2, ..., A_n}\) 的最大值。

题解

首先,如果 \(K\) 可以把当前序列中所有的数都加到 \(A_{\max}\),那就全部加到 \(A_{\max}\),在此基础上同步对所有数相加即可。

如果 \(K\) 不足以把当前序列中所有的数都加到 \(A_{\max}\),那么可以发现最后的答案 \(Ans \le A_{\max}\),因为 \(A_{\max} \le 3 \times 10^5\),所以可以直接枚举判断当前答案是否成立。

可以把原题的条件进行转化

\[\gcd{A_1, A_2, ..., A_n} = Ans \Rightarrow Ans \mid {A_1, A_2, ..., A_n} \]

又因为题目要求的是最大值,所以从大到小枚举即可。接下来考虑如何判定。

设当前枚举的答案是 \(x\),那么对于序列中的数 \(A_i\),它应当被加到 \(kx \ge A_i\),考虑枚举 \(k\) 进行判定,使用前缀和记录序列中一定值域中的数的个数和和即可求解。

设 \(M = A_{\max}\),则最终的复杂度为 \(\mathcal{O}(N + M \times \sum\limits_{i = 1}^{M} \dfrac{1}{i}) = \mathcal{O}(N + M \log M)\)。

Code

#include <bits/stdc++.h>

typedef long long valueType;
typedef std::vector<valueType> ValueVector;

class TreeArray {
public:
    typedef ValueVector container;
private:
    valueType size;
    container data;

    static valueType lowBit(valueType x) {
        return x & -x;
    }

public:
    explicit TreeArray(valueType n) : size(n), data(size + 1, 0) {};

    void insert(valueType pos, valueType key) {
        while (pos < size) {
            data[pos] += key;

            pos += lowBit(pos);
        }
    }

    valueType sum(valueType pos) const {
        valueType result = 0;

        while (pos > 0) {
            result += data[pos];

            pos -= lowBit(pos);
        }

        return result;
    }
};

constexpr valueType \maxA = 6e5 + 5;

int main() {
    std::ios_base::sync_with_stdio(false);

    valueType N, K;

    std::cin >> N >> K;

    if (N == 1) {
        valueType A;

        std::cin >> A;

        std::cout << (A + K) << std::endl;

        return 0;
    }

    ValueVector source(N);

    for (auto &iter: source)
        std::cin >> iter;

    TreeArray sum(\maxA), count(\maxA);

    valueType \max = 0;

    for (auto const &iter: source) {
        \max = std::\max(\max, iter);

        sum.insert(iter, iter);
        count.insert(iter, 1);
    }

    typedef std::function<bool(valueType)> CheckFunction;

    CheckFunction check = [\max, &sum, &count, K](valueType n) -> bool {
        valueType result = 0;

        for (valueType i = n; i <= \max + n; i += n)
            result += i * (count.sum(i) - count.sum(i - n)) - (sum.sum(i) - sum.sum(i - n));

        return result <= K;
    };

    valueType const minK = N * \max - sum.sum(\max);

    if (K >= minK) {
        std::cout << (\max + (K - minK) / N) << std::endl;
    } else {
        for (valueType i = \max; i >= 1; --i) {
            if (check(i)) {
                std::cout << i << std::endl;

                return 0;
            }
        }
    }
    return 0;
}

标签:std,GCD,题解,valueType,ARC126C,pos,iter,max,sum
From: https://www.cnblogs.com/User-Unauthorized/p/solution-at-arc126-c.html

相关文章

  • [ABC215D] Coprime 2 题解
    题意给定数列\(A_N\)和一个正整数\(M\),求出所有的\(1\lek\leM\)满足\(\foralli\in\left[1,N\right],\gcd(k,A_i)=1\)。题解本题存在线性复杂度算法。记\(\operatorname{lpf}(n)=[1<n]\min\{p:p\midn\}+[1=n]\),即\(n\)的最小质因数。特别地,\(n......
  • [ARC126D] Pure Straight 题解
    题意给定一个有\(N\)个正整数的序列\(A=(A_1,A_2,\cdots,A_N)\),且\(A_i\in\left[1,K\right]\)。你可以对这个序列做如下操作若干次。交换两个相邻的元素,也就是选出\(i\)和\(j\)满足\(\lverti-j\rvert=1\)并交换\(A_i\)和\(A_j\)。找到最小的操作数使\(......
  • CF793F Julia the snail 题解
    题意有一个长为\(n\)的杆,上面有\(m\)条绳子,每条绳子可以让蜗牛从\(l_i\)爬到\(r_i\)(中途不能离开),保证\(r_i\)各不相同。蜗牛也可以自然下落。现在有\(q\)次询问,询问\(x\)出发,途中高度不能低于\(x\)或高于\(y\),问最高能爬到的位置。\(n,m,q\leq10^5\)。题解......
  • 【免费分享 图书】《阿里云天池大赛赛题解析——机器学习篇》-PDF电子书-百度云
    找这本书的资源简直要把我找吐了,各种网站压缩包一下下来就开始各种套路(比如要你充钱)为了防止还有我这样的受害者,这就把找到的PDF给大家分享一下。链接在文章最后如果这篇文章能够帮到您,麻烦帮我点个赞,并关注一下我,我有更多动力,持续分享更多有用图书给您!非常感谢,不胜感激!(点关......
  • 「题解注释」P3345 [ZJOI2015] 幻想乡战略游戏
    题解P3345【[ZJOI2015]幻想乡战略游戏】-Baka'sBlog-洛谷博客(luogu.org)耗时:半个下午代码注释:#include<bits/stdc++.h>typedeflonglongLL;inlineintrd(){ inta=1,b=0;charc=getchar(); while(!isdigit(c))a=c=='-'?0:1,c=getcha......
  • CF1859C 题解
    思路我们实际上发现它计算的就是\(p_i\cdoti\)的和再减去一个\(p_i\cdoti\)中的最大值。那我们可以枚举这个最大值\(p_x\cdotx\),这个值就是最后和中需要删除的数值。这里我们可以使用贪心。我们可以从\(n\sim1\)枚举除\(p_i\)的每个数字需要配的数字。当然,......
  • CF1859B 题解
    题意给定\(n\)个长度为\(m\)的数组,每个数组可以向别的数组转移最多一个数字,任意一个数组都可以接受无穷多的数字,最大化每个数组的最小值之和。做法考虑贪心。我们记第\(i\)个数组的第\(j\)个数字为\(a_{i,j}\)。我们先对每一个数组按照升序进行排序,那我们最不愿意......
  • 【题解】 Call Me Call Me CCPC Mianyang 2022
    https://codeforces.com/gym/104065/原题做法是类似猫树转成前缀后缀,写起来太麻烦,不如如下做法:如果每个区间所需满足的点不超过\(\sqrt{n}\)个,即可以如下暴力:把每个区间拍到线段树上,每次更新一个点,则在线段树上把所有包含他的区间全部\(-1\)看看是否减到了\(0\),拿个队列一......
  • 问题解答:关于 SAP UI5 控制器(Controller) JavaScript 编码里单引号和双引号的用法澄
    笔者这篇教程文末,有朋友提问:SAPUI5应用开发教程之十-什么是SAPUI5应用的描述符文件manifest.json问题1:在index.html文件中body标签添加了代码:<divdata-sap-ui-componentdata-name="sap.ui5.walkthrough"data-id="container"data-settings='{"id":"wa......
  • ARC129C 题解
    problem&blog。提供一种不一样的做法喵。考虑原问题的逆问题。这个很典,直接前缀和\(sum_i\)表示\([1,i]\)顺次拼接的数\(\bmod7\)的值,那么\([l,r]\)符合条件当且仅当\(sum_r-sum_{l-1}=0\),即\(sum_r=sum_{l-1}\)。设\(c_p=\sum\limits_{i=1}^n[sum_i=p]\),这个逆......