1213D2.Equalizing by Division(hard version)(图论)

简单版本和硬版本之间的惟一区别是数组中的元素数量。

给你一个由n个整数组成的数组。在一个你可以选择任何ai,除以2舍去小数(换句话说,在一个动作你可以设置ai: =⌊ai2⌋)。

你可以用任何ai执行这样的操作任意次数(可能是零次)。

您的任务是计算获得数组中至少k个相等数字所需的最小操作数。

不要忘记在某些操作之后ai=0是可能的,因此答案总是存在的。

题解:

开一个邻接表,把每个数对应的操作数量与这个数连边建图,然后遍历每个数,如果这个点的度大于K,说明是可以通过操作实现的,把每个点连的值加起来就是总操作数,比较所有总操作数,取最小值,就是答案。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
int N,K;
vector<int> g[maxn];
int main () {
    scanf("%d%d",&N,&K);
    for (int i=1;i<=N;i++) {
        int x;
        scanf("%d",&x);
        int ans=0;
        while (x) {
            g[x].push_back(ans);
            x/=2;
            ans++;
        }
    }
    int Min=1e9;
    for (int i=1;i<=2e5;i++) {
        if (g[i].size()>=K) {
            sort(g[i].begin(),g[i].end());
            int sum=0;
            for (int j=0;j<K;j++) sum+=g[i][j];
            Min=min(Min,sum);
        }
    }
    printf("%d\n",Min);
}

猜你喜欢

转载自www.cnblogs.com/zhanglichen/p/12687449.html