首页 > 其他分享 >[ARC106E] Medals 题解

[ARC106E] Medals 题解

时间:2023-11-13 18:03:08浏览次数:34  
标签:std le 联通 题解 点集 判定 右部点 ARC106E Medals

题意

有一个商店和 \(N\) 名员工,其中第 \(i\) 名员工在第 \(1 \sim A_i\) 天工作,在第 \(A_i + 1 \sim 2 \times A_i\) 休息,接下来每 \(A_i\) 天改变一次状态。

每一天你都可以选择一名来上班的员工并为其颁一个奖,求使得每名员工都获得至少 \(K\) 个奖的最小天数。

  • \(1 \le N \le 18\)
  • \(1 \le K \le 10^5\)
  • \(1 \le A_i \le 10^5\)

题解

首先考虑二分答案。

现在问题转化为了判定在制定天数内是否可以使得每名员工都获得至少 \(K\) 个奖。

考虑转化为二分图模型,将员工视为左部点,天数视为右部点,那么判定成立当且仅当存在一个完美匹配使得每个员工都有 \(K\) 条边。

将原图中的每个员工拆为 \(K\) 个点,那么判定成立当且仅当对左部图存在一个完美匹配。

考虑应用 Hall 定理,发现对于一个员工拆出的 \(K\) 个点,由于与其联通的右部点集合均相同,故对全部 \(K\) 个点整体判定强于对部分点进行判定。因此需要判定的点集只有 \(2^N\) 个。

考虑如何判定,问题转化为了对于每个点集,求出与其联通的右部点点集大小。

可以发现一个性质,即对于每个点集,与其相邻的右部点数量不少于全体右部点数量的一半。因此可以得出答案上界为 \(2 \times N \times K\)。因此我们只需要对 \(\left[N \cdot K, 2 \times N \times K\right]\) 内的答案进行判定。

根据上述分析可以得出右部点数量是 \(\mathcal{O}(NK)\) 级别的,所以我们从右部点的角度来考虑。同样可以发现,对于右部点,与其联通的左部点集合之后 \(2^N\) 种,且可以进行预处理。

那么我们可以对于每个左部点集合 \(S\),求有多少个右部点的联通集合与其有交,发现难于计算,转化为求有多少个个右部点的联通集合与其不交,发现其数量等于联通集合为 \(S\) 的点集的补集的右部点数量。这个是便于处理的,使用高维前缀和即可。

因此我们可以通过对于所有可能的右部点,处理出与其联通的左部点集合,这可以在 \(\mathcal{O}(N^2K)\) 的时间内完成。

接下来对于每次判定,对于每个点集 \(S\),处理出恰好与这些左部点联通的右部点数量。接下来使用高维前缀和处理出对于每个点集 \(S\),与左部点联通集合为其子集的右部点数量。最后枚举所有点集进行判定即可。这部分的复杂度为 \(\mathcal{O}(NK + N2^N)\)。

总复杂度为 \(\mathcal{O}\left(N^2K + \log NK \left(NK + N2^N\right)\right)\),可以通过。

Code

#include <bits/stdc++.h>

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

valueType popcount(valueType n) {
    return __builtin_popcount(n);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    valueType N, K;

    std::cin >> N >> K;

    ValueVector A(N);

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

    valueType const V = 2 * N * K, S = 1 << N, FULL = S - 1;

    ValueVector type(V + 1, 0);

    for (valueType i = 1; i <= V; ++i) {
        for (valueType j = 0; j < N; ++j)
            if ((i - 1) / A[j] % 2 == 0)
                type[i] |= 1 << j;
    }

    auto check = [&](valueType lim) -> bool {
        ValueVector F(S, 0);

        for (valueType i = 1; i <= lim; ++i)
            ++F[type[i]];

        for (valueType i = 0; i < N; ++i)
            for (valueType j = 0; j < S; ++j)
                if (j & (1 << i))
                    F[j] += F[j ^ (1 << i)];

        for (valueType i = 0; i < S; ++i)
            if (lim - F[FULL ^ i] < popcount(i) * K)
                return false;

        return true;
    };

    valueType left = 1, right = V, ans = V;

    while (left <= right) {
        valueType const mid = (left + right) / 2;

        if (check(mid)) {
            ans = mid;
            right = mid - 1;
        } else
            left = mid + 1;
    }

    std::cout << ans << std::endl;

    return 0;
}

标签:std,le,联通,题解,点集,判定,右部点,ARC106E,Medals
From: https://www.cnblogs.com/User-Unauthorized/p/solution-ARC106E.html

相关文章

  • [题解] CF1156E Special Segments of Permutation
    SpecialSegmentsofPermutation给你一个排列\(p\),求有多少个区间\([l,r]\)满足\(p_l+p_r=\max_{i\in[l,r]}p_i\)。\(n\le2\times10^5\)。按最大值分治,记当前的分治中心为\(mid\),分治区间为\([l,r]\)。然后需要计算跨分治中心的贡献。如果\(mid-l......
  • [题解]AT_abc328_f [ABC328F] Good Set Query
    思路带权并查集模板。如果对于一个三元组\((a,b,c)\)如果它能够添加到\(S\)中一定满足如下条件中的一条:\(X_a,X_b\)满足其中有一个是「不确定」的。在这里\(X_i\)「不确定」指\(X_i\)没有与其它的任意\(X_j\)有关系。\(X_a,X_b\)有间接或直接的关系,但是能计算......
  • CF300B Coach 题解
    闲话调了好一会,甚至还重构了一次代码才对,但是还是很喜欢并查集,并查集可爱捏。题意省流$n$个学生分成$3$人一组,要满足$m$个条件,每个条件给出两个数$x,y$,要求$x$和$y$必须在一个组里。正文要使学生三人一组,一眼使用并查集。首先考虑无解(输出$-1$)的情况:给出的限......
  • 【题解 P8476】 惊蛰
    「GLR-R3」惊蛰题目背景  「微雨众卉新,一雷惊蛰始」  中午,休息室,阿绫肩膀上。  “我有一个愿望,参加全国音乐祭,获奖,和阿绫一起,摆脱这训练的苦海。”  “为热爱而到来,为抽身而努力……吗”。  正午的阳光渗过窗帘,抚上困倦的人儿的脸颊。天依的左手悄悄搭上阿绫怀里......
  • NOJ题解
    NOJ题解30-40素数埃氏筛,欧拉筛都可可变参数累加/平均用给出的库函数即可基思数根据题意模拟#include<stdio.h>#definelllonglongllnum[102];inlineboolIsKeith(lln){inttot=0,t=0;lls=n;while(s){num[++tot]=s%10......
  • 问题解答:SAP OData V2 和 V4 里针对日期类型的字段进行过滤操作(filter)的正确语法试
    我的知识星球里有朋友咨询一个问题:我测试了一个S/4HANAcloud的purchaseorder的API,这个是ODATAV4格式的。在对CreationDate做filter后运行有报错Invalidparametertypeusedwithfunction'eq'.对datetime字段做filter,一直搞不清楚格式。请帮忙看一下。本文就安排这......
  • [题解] P6569 [NOI Online #3 提高组] 魔法值
    P6569[NOIOnline#3提高组]魔法值不放简要题意了,题面写的很简要。看到数据范围自然可以想到矩阵快速幂优化。但乘法对异或没有分配律。所以直接拆位,把异或变成加法对二取模就有分配律了。还有一个优化就是提前预处理出矩阵的2的幂次方,然后询问时直接二进制分解乘起来就行......
  • ARC119F 题解
    前言ARC119F好厉害,是没见过的自动机DP。正文[1]分析主要分析一下为什么这么写。[2]状态设计[3]自动机状态转移感觉状态设计中最难的就是如何处理带\(O\)的。见参考资料。[4]代码还没写。写ing这是自动机的初始化(有点麻烦)。intto[Kind][2][2]={{{2,0},{8,0......
  • ABC328F题解
    原题链接洛谷题面提交记录闲话赛场就做了这道和A,喜提\(625\)大分。带权并查集练手题,有点像银河英雄传说。题目大意存在一个长度为\(N\)的数列\(X\),给定\(Q\)个三元组\((a_i,b_i,d_i)\),定义一个好集合为集合\(S\subseteq\{1,2,\dots,Q\}\),使得所有\(x\inS\)满......
  • 题解:[春季测试 2023] 幂次
    题解:[春季测试2023]幂次给定\(n,k\),求有多少个整数\(i\in[1,n]\),满足\(i=a^b(a,b\inN^+,b\geqk)\)算法一\(k\ge3:\)发现只需要筛到1e6就没有贡献了,加上\(set\)暴力判重即可。\(k=2:\)发现有\(\sqrt{n}\)个完全平方数,考虑如何避免算重它们。考虑完全平......