首页 > 其他分享 >CF1188D Make Equal 题解

CF1188D Make Equal 题解

时间:2023-08-15 19:34:28浏览次数:42  
标签:std nowCount 题解 Make allCount source CF1188D Delta valueType

题意

给定 \(n\) 个数 \(a_1, a_2, \cdots, a_n\),每次操作可以给其中的一个数加上 \(2\) 的非负整数次幂。求最小的操作次数,使得这 \(n\) 个数相等。

题解

首先考虑如何计算操作次数,设 \(maxa = \max\limits_{i = 1}^{n} a_i\),如果我们把这 \(n\) 个数操作成了数 \(x\)(\(x \ge maxa\)),那么一共需要的操作次数为 \(\sum\limits_{i = 1}^{n} \operatorname{popcount\left(x - a_i\right)}\)。我们设 \(\Delta = x - maxa, b_i = maxa - a_i\),那么需要的操作次数为 \(\sum\limits_{i = 1}^{n} \operatorname{popcount\left(\Delta + b_i\right)}\)。这样我们就可以把问题转化为求出一个 \(\Delta\),最小化 \(\sum\limits_{i = 1}^{n} \operatorname{popcount\left(\Delta + b_i\right)}\)。

因为涉及到了位运算,我们考虑从低到高按位决策 \(\Delta\) 的值,影响第 \(i\) 位操作次数的因素有三:

  1. \(\Delta\) 在第 \(i\) 位的取值;
  2. \(b_k\) 在第 \(i\) 位的取值;
  3. \(b_k + \Delta\) 在第 \(i - 1\) 位是否会产生进位。

发现二进制下在第 \(i\) 位越容易进位的数在模 \(2^i\) 下越大,所以再处理每一位的时候可以先将 \(b_i\) 按模 \(2^i\) 的值降序排序,这样的话如果有 \(j\) 个数进位,那么一定是排序后的前 \(j\) 个数。

这样我们就可以设计出状态了。设 \(f_{i, j}\) 表示在二进制表示下有 \(j\) 个数进位到了第 \(i\) 位时的最优解。

接下来考虑转移,发现我们只需要处理当前二进制下第 \(i\) 位是否为 \(1\)和在第 \(i - 1\) 位进位的数个数 \(j\)。那么一共有 \(4\) 种数。接下来的讨论钦定上一位有 \(j\) 个数进位。

令 \(allCount\) 为这一位下为 \(1\) 的 \(b_k\) 的个数,\(nowCount\) 为这一位下为 \(1\) 且 \(k \le j\) 的 \(b_k\) 的个数。

  1. \(b_k + \Delta\) 在第 \(i - 1\) 位产生进位且 \(b_k\) 的第 \(i\) 位为 \(1\),有 \(nowCount\) 个。
  2. \(b_k + \Delta\) 在第 \(i - 1\) 位产生进位且 \(b_k\) 的第 \(i\) 位为 \(0\),有 \(j - nowCount\) 个。
  3. \(b_k + \Delta\) 在第 \(i - 1\) 位没有进位且 \(b_k\) 的第 \(i\) 位为 \(1\),有 \(allCount - nowCount\) 个。
  4. \(b_k + \Delta\) 在第 \(i - 1\) 位没有进位且 \(b_k\) 的第 \(i\) 位为 \(0\),有 \(n - j - \left(allCount - nowCount\right)\) 个。

那么我们考虑 \(\Delta\) 在第 \(i\) 位如何决策。

  • 如果 \(\Delta\) 取 \(1\),那么第 \(1, 2, 3\) 种数会产生进位,第 \(1, 4\) 种数的 \(\Delta + b_k\) 这一位是 \(1\),需要进行操作。
  • 如果 \(\Delta\) 取 \(0\),那么第 \(1\) 种数会产生进位,第 \(2, 3\) 种数的 \(\Delta + b_k\) 这一位是 \(1\),需要进行操作。

所以我们可以得出转移式:

\[\begin{aligned}f_{i + 1, allCount - nowCount + j} &= \min{f_{i, j} + nowCount + \left(n - j\right) - \left(allCount - nowCount\right)} \\ f_{i + 1, nowCount} &= \min{f_{i, j} + j - nowCount + allCount - nowCount}\end{aligned}\]

至此我们就可以以 \(\mathcal{O}(n \log n \log a)\) 的复杂度通过本题。

Code

#include <bits/stdc++.h>

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

constexpr valueType maxB = 58;
constexpr valueType MIN = LONG_LONG_MIN >> 8, MAX = LONG_LONG_MAX >> 8;

typedef std::array<valueType, maxB> BitArray;
typedef std::bitset<maxB> bitset;
typedef std::vector<bitset> BitsetVector;

valueType popcount(valueType x) {
    return __builtin_popcountll(x);
}

constexpr std::array<valueType, maxB> bin = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 31072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648, 4294967296, 8589934592, 17179869184, 34359738368, 68719476736, 137438953472, 274877906944, 549755813888, 1099511627776, 2199023255552, 4398046511104, 8796093022208, 17592186044416, 5184372088832, 70368744177664, 140737488355328, 281474976710656, 562949953421312, 1125899906842624, 2251799813685248, 4503599627370496, 9007199254740992, 18014398509481984, 36028797018963968, 72057594037927936, 144115188075855872};

class ModCompare {
private:
    valueType mod;

public:
    explicit ModCompare(valueType mod) : mod(mod) {}

    bool operator()(valueType a, valueType b) const {
        return a % mod > b % mod;
    }

    void setMod(valueType m) {
        mod = m;
    }
};

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

    valueType N;

    std::cin >> N;

    ValueVector source(N);

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

    valueType const maxNumber = *std::max_element(source.begin(), source.end());

    for (auto &iter: source)
        iter = maxNumber - iter;

    BitArray bitCount;

    for (valueType i = 0; i < maxB; ++i)
        for (auto const &iter: source)
            if (iter & bin[i])
                ++bitCount[i];

    ValueMatrix dp(maxB, ValueVector(N + 1, MAX));

    dp[0][0] = 0;

    for (valueType i = 0; i < maxB - 1; ++i) {
        if (i > 0)
            std::sort(source.begin(), source.end(), ModCompare(bin[i]));

        valueType allCount = 0, nowCount = 0;

        for (auto const &iter: source)
            if (iter & bin[i])
                ++allCount;

        for (valueType j = 0; j <= N; ++j) {
            if (j > 0 && source[j - 1] & bin[i])
                ++nowCount;

            dp[i + 1][allCount - nowCount + j] = std::min(dp[i + 1][allCount - nowCount + j], dp[i][j] + nowCount + (N - j) - (allCount - nowCount));

            dp[i + 1][nowCount] = std::min(dp[i + 1][nowCount], dp[i][j] + j - nowCount + allCount - nowCount);
        }
    }

    std::cout << dp[maxB - 1][0] << std::endl;

    return 0;
}

标签:std,nowCount,题解,Make,allCount,source,CF1188D,Delta,valueType
From: https://www.cnblogs.com/User-Unauthorized/p/solution-CF1188D.html

相关文章

  • [ARC096E] Everything on It 题解
    题意对于集合\({1,2,\cdots,n}\),求它的子集族中,有多少个满足:任意两个子集互不相同;\(1,2,\cdots,n\)都在其中至少出现了\(2\)次。\(n\le3000\),答案对\(M\)取模。题解第一个限制形同虚设,下面着重考虑第二个限制。考虑到第二个限制集合的每个元素都是等价的,考虑二项......
  • [ABC134F] Permutation Oddness 题解
    题面定义一个\(1\simn\)的排列\(p\)的「怪异度」为\[\sum_{i=1}^n\left\lvertp_i-i\right\rvert\]求「怪异度」为\(k\)的\(1\simn\)的排列数,答案对\(10^9+7\)取模。题解考虑转化计算怪异度的过程,我们将值\(p_i\)排列在左侧,将下标\(i\)排列在右侧,构成一个......
  • CF1188D Make Equal
    题目大意给出\(n\)个数字\(a_1,a_2,\dots,a_n\),每次操作可以给其中一个数加上\(2\)的非负整数次幂。求最少的操作次数,使得这\(n\)个数相等。思路记\(b_i=\max\limits_{1\leqk\leqn}{a_k}-a_i\),这道题的目的是求一个值\(x\)使得\[\sum_{i=1}^n\operatorname......
  • 『题解』ABC261Ex Game on Graph
    题目链接震惊!这个题竟然被神犇szs放进了博弈论里!我真的没看出来除了题面还有哪里像博弈论(也许是因为我菜)。转移方式很显然,按照题面说的做就行了。那么正解也就呼之欲出了。但是我知道大家都会正解,就是魔改的堆优化Dijkstra,所以我想说的是一种歪解,以及它是歪解的原因。歪解......
  • 国标GB28181视频平台EasyGBS国标平台设备播放断流现象的问题解决方案
    安防视频监控EasyGBS平台基于国标GB28181协议,支持多路设备接入,并对多平台、多终端分发出RTSP、RTMP、FLV、HLS、WebRTC等多种格式的视频流。平台可为大数据等综合性监管平台提供极强的视频能力,已经在大量的项目中落地应用,如明厨亮灶、平安乡村、雪亮工程等。有用户反馈,在安防视频监......
  • 视频汇聚平台EasyCVR安防监控视频汇聚平台的FLV视频流在VLC中无法播放的问题解决方案
    众所周知,TSINGSEE青犀视频汇聚平台EasyCVR可支持多协议方式接入,包括主流标准协议国标GB28181、RTSP/Onvif、RTMP等,以及厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。在视频流的处理与分发上,视频监控汇聚平台EasyCVR的性能也同样表现得很优秀,平台可对外分发多格式的视......
  • [Luogu P8716] 回文日期 题解
    STEP1:分析题目大意:给定一个8位数的日期,请你计算该日期之后下一个回文日期和下一个ABABBABA型的回文日期各是哪一天。这一题一眼看出是P2010的升级版,所以要先考虑到超时问题,因为如果一天一天地枚举,时间复杂度会非常高,所以我们不能直接枚举。因为题目只要"回文",所以我们只......
  • [JOI 2023 Final] Advertisement 2 题解
    题解JOI王国有\(N\)位居民,从\(1\)到\(N\)编号。居民\(i\)(\(1\lei\leN\))居住在数轴上坐标\(X_i\)处,其影响力为\(E_i\)。同一个坐标可能住了多于一位居民。居民的影响力越高,广告效应也越高,但买书也越谨慎。Rie出版了一本关于信息学的书。为了让更多人购买这本书,她可......
  • CMakeLists语法详解
     https://www.jianshu.com/p/eb25baf5ca19set(Root"${CMAKE_CURRENT_SOURCE_DIR}")set(Base64${Root}/lib/libb64/src)include_directories(${OpenCV_INCLUDE_DIRS})include_directories(${Root})include_directories(${Root}/lib/libb64/include) include_dir......
  • 【免费分享 图书】《阿里云天池大赛赛题解析——深度学习篇》-PDF电子书-百度云
    找这本书的资源简直要把我找吐了,各种网站压缩包一下下来就开始各种套路(比如要你充钱)为了防止还有我这样的受害者,这就把找到的PDF给大家分享一下。链接在文章最后如果这篇文章能够帮到您,麻烦帮我点个赞,并关注一下我,我将有更多动力,持续分享更多有用图书给您!非常感谢,不胜感激!(点......