首页 > 其他分享 >【题解】Imbalanced Arrays - Codeforces 1852B

【题解】Imbalanced Arrays - Codeforces 1852B

时间:2023-07-24 20:33:34浏览次数:42  
标签:int 题解 频次 Arrays curB 序列 Imbalanced 引理 相反数

出处: Codeforces Round 887

链接: https://codeforces.com/problemset/problem/1852/B


题目大意:

给定一个包含 \(n\) 个非负整数的频次序列 \(f\) 。

构造任意一个等长的整数序列 \(b\) ,要求
① \(b \in [-n, n]\) but $b \neq 0 $
② \(b\) 中不存在相反数
③ 对于每个坐标 \(i\) ,序列中的(可以和 \(i\) 重复的)坐标 \(j\) ,且能满足 \(b_i+b_j>0\) 的 \(j\) 的个数刚好为 \(f_i\) 频次
说明不存在这样的 \(b\) 满足这个条件。

约束: \(1\leq n \leq 10^5\) , \(0\leq f_i \leq 10^5\) 。


解题思路:

  1. 先观察有什么规律

    构造 \(b\) 序列时的前两个要求,其实变相说明了只能从 \(\{-n,n\}, \{-n+1, n-1\}, \dots, \{-1, 1\}\) 里面每组挑选至多一个作为值出现。

    引理1:假设要选出 \(6\) 个不同的值,则选出的值必定满足以下两种模式其中之一:① \(-6,-4,-2,1,3,5\) 或者 \(-5,-3,-1,2,4,6\) 。证明似乎是显然的,因为构造 \(b\) 序列时的前两个要求导致的。

    引理2:假如要选出 \(n\) 个值,并且运行一部分的值重复,得到的序列依然满足上一条引理约束的模式。也就是对于 \(0\) 的同一侧,距离必定相差为 \(2\) ,且 \(0\) 的两侧的奇偶值必定相反,且一定从 \(-2,-1,1,2\) 这样的值开始。首先先证明为什么距离必定是 \(2\) ,因为假如距离大于 \(2\) 则中间可以插入另一个相反数,而几个连续的相反数之间对于是否和对侧的相反数加起来超过 \(0\) 是没有变化的,也就是说他们是等价的。比如对于 \(-6,-2\) 来说, \(3,4,5\) 其实是完全等价的。没有意义,可以约简为 \(3\) ,进而把 \(-6\) 约简为 \(-4\) ,转换成上一条引理约束的形式。

    引理3:越大的频次,对应的 \(b\) 值应该越大。这是一个显然的单调性。

    引理4:相同的频次,对应相同的 \(b\) 值。这个没有那么明显,但用反证法去看也是一样的。如果某个相同的频次 \(f\) 对应的 \(b\) 值不同,那么这两个 \(b\) 值中间不能插入其他的相反数,否则会导致频次至少相差 \(1\) ,矛盾。

    引理5:相同的 \(b\) 值,对应相同的频次。这个很明显,因为 \(b\) 序列确定了之后,是跟位置完全无关的,所以一定会得到相同的频次。

    根据上面的引理,可以知道一个约简的办法,就是先数一数有多少种不同的频次,记为 \(cntF\) 种,那么只需要验证引理1中的两个模式的 \(b\) 序列即可知道是否有解,其他的模式一定完全等价于这两个模式。并且由于引理3和引理4,可以知道每一个 \(b\) 值是和某一个频次唯一一一对应的。

  2. 算法和复杂度细节

    既然知道了构造的方法是唯一(唯二?)的,那么只需要编程就行了。

    由于引理3,所以要对频次进行一个排序(同时要保留原本输入的顺序用以输出,可以用常见的 pair<int, int>sort 搞定。),排序之后就可以贪心去给每个频次分配一个 \(b\) 值。复杂度为 \(O(nlogn)\) 。

    构造出 \(b\) 序列之后,在验证频次是否合理的过程中,也可以使用双指针等方法进行加速,实在偷懒可以用一个树状数组啥的。复杂度为 \(O(n)\) 。

    构造出第一个 \(b\) 序列之后,再构造另一个重新计算一次,注意这里要特别处理经过 \(0\) 的情况。

点击查看代码
int n;
pii f[200005];
int b[200005];
int sortB[200005];

bool check (int cntF) {
    if (cntF == 0) {
        // 非常重要,要避开 0 !!!
        --cntF;
    }
    int curB = cntF;
    for (int i = 1; i <= n; ++i) {
        if (i > 1 && f[i].first != f[i - 1].first) {
            // b 序列中, 0 的同一侧,相邻的值差为 2
            curB -= 2;
            if (curB == 0 || curB == -1) {
                // 如果 -2 之后越过了0,说明之前是 2 或者 1,这里要避开 0 或者 -1
                --curB;
            }
        }
        b[f[i].second] = curB;
        sortB[i] = curB;
    }

    int r = n;  // 用双指针法计算 b[i] + b[j] > 0 的频次
    for (int i = 1; i <= n; ++i) {
        while (r > 0 && sortB[r] + sortB[i] <= 0) {
            --r;
        }
        // sortB[r] + sort[i] > 0
        if (f[i].first != r) {
            return false;
        }
    }
    return true;
}

void solve() {
    RD (n);
    for (int i = 1; i <= n; ++i) {
        RD (f[i].first);
        f[i].second = i;
    }
    sort (f + 1, f + 1 + n);
    reverse (f + 1, f + 1 + n); // 套引理3,从大到小进行构造

    int cntF = 0;
    for (int i = 1; i <= n; ++i) {
        if (i == 1 || f[i].first != f[i - 1].first) {
            ++cntF; // 计算一共有多少种不同的频次,用于套引理1进行构造
        }
    }

    if (check (cntF) || check (cntF - 1)) {
        // 对于偶数:
        // 6, 4, 2, -1, -3, -5
        // 5, 3, 1, -2, -4, -6
        // 对于奇数:
        // 7, 5, 3, 1, -2, -4, -6
        // 6, 4, 2, -1, -3, -5, -7
        puts ("YES");
        WTN (b, n);
    } else {
        puts ("NO");
    }
}
  1. 用此算法计算出的 \(b\) 是绝对值之和最小的 \(b\) ,与官方题解的答案略有不同。

标签:int,题解,频次,Arrays,curB,序列,Imbalanced,引理,相反数
From: https://www.cnblogs.com/purinliang/p/17578278.html

相关文章

  • 【P8302 题解】
    Solution设\(g(x)\)表示\(x\)的最小质因子。则\(f(x)=n+\dfrac{n}{g(x)}=\dfrac{g(x)+1}{g(x)}\timesn\)。分情况讨论:\(g(x)=2\),经过\(1\)次变换之后,\(f(x)\)增加了一个因子\(3\),减少了一个因子\(2\)。\(g(x)>2\),则满足\(g(x)\nmid2\),否则与最小质因子矛盾,......
  • 【题解】Ntarsis' Set - Codeforces 1852A
    出处:CodeforcesRound887链接:https://codeforces.com/problemset/problem/1852/A题目大意:给定一个包含\(n\)个正整数的表示删除位置的严格升序序列\(p\),以及另外一个连续正整数的被删除的无穷序列\(l\)。进行\(k\)次删除操作,每次操作从无穷序列\(l\)中同时删除位......
  • Codeforces Round 887 (Div. 1) 题解
    https://codeforces.com/contest/1852/problemsA.Ntarsis'Sethttps://codeforces.com/contest/1852/problem/A感觉不是很一眼。\(n\)和\(k\)都是\(2\times10^5\),不能暴力,设当前集合为\({1,2,\dots,10^{1000}}\),那么被操作过一次的最小值就应该是\(\text{MEX}(0,......
  • 国标GB28181视频平台LntonGBS(含源码)国标视频平台播放视频时偶尔出现播放失败的问题解
    LntonGBS是基于公安部推出的安防主流协议(国标GB28181协议)的视频接入、处理及分发平台,具有视频直播监控、云端录像、云存储、检索回放、智能告警、语音对讲等功能,能够涵盖所有监控领域的视频能力需求,已经在大量的项目中落地应用,如明厨亮灶、平安乡村、雪亮工程等。有用户反馈,在某项......
  • P7831 题解
    problem&blog。妙妙题。单杀了,来写篇题解。下文中\(ans_u\)表示从\(u\)点出发的答案。考虑直接做。发现更新任何一个点,都可能会对一堆点造成影响,\(O(n^2)\)无法接受。一些简单的性质:不能进入一个环的\(ans_u=-1\)。否则,对于\((u,v,r,p)\),\(r\)是最大的\(r\),那么只......
  • AT_abc218_d 题解
    洛谷链接&Atcoder本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读。题目简述给定一个平面内的\(N\)个点的坐标,求这\(N\)个点中选\(4\)个点可构成正方形的方案数。注:构成的正方形的边需平行于\(x\)轴或\(y\)轴。例如下图就不符合要求,则不考虑这种情况:......
  • AT_abc215_d 题解
    洛谷链接&Atcoder链接本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读。题目简述给定\(N\),\(M\)及含有\(N\)个整数的序列\(A\)。求\(1\simM\)中与所有\(a_i\)均互质的整数及个数。思路首先说一下最开始的想法。直接暴力枚举\(1\simM\)的数,再分......
  • 仪酷LabVIEW AI视觉工具包及开放神经网络交互工具包常见问题解答
    前言哈喽,各位朋友,好久不见~之前给大家分享了基于LabVIEW开发的AI视觉工具包及开放神经网络交互工具包,不少朋友私信说在安装和使用过程中会遇到一些问题,今天我们就集中回复一下大家问到最多的问题。如果大家在使用过程中还有其他问题,可以补充到评论区,我们这篇博文会持续补充更新......
  • 「题解」Codeforces Round 887 (Div. 2)
    A.DesortingProblem题目Sol&Code若序列一开始无序答案为\(0\)若有序即\(a_1\leqa_2\leq\dots\leqa_n\)。若想让\(a_i>a_j(i<j)\),操作次数与两数差值\(d(d=a_j-a_i)\)相关为\(\lfloor\dfrac{d}{2}\rfloor+1\),差值越小操作次数越少,故枚举相邻两数取最少......
  • 洛谷AT_jsc2019_qual_e Card Collector 题解
    题目链接CardCollector-洛谷|计算机科学教育新生态(luogu.com.cn)思路将每一行、每一列转化为点,第i行第j列的卡牌转化为i->j+m(m为行数)的有向边。总共会抽取m+n(m为行数,n为列数)张牌,每个点的出度为1。结果图为基环森林;那么题目就转化为求最大基环森林。代码1#include......