浅谈一类第 k 大问题

news/2024/9/13 11:29:06/文章来源:https://www.cnblogs.com/bluewindde/p/18378410

浅谈一类第 k 大问题

Introduction to K-th Largest Problems

本文介绍一类第 k 大问题的处理方法。

Luogu P1631 序列合并
Luogu P2048 [NOI2010] 超级钢琴
Luogu P5283 [十二省联考 2019] 异或粽子
CodeForces 241B Friends

基本思想:先找到部分答案,通过这部分答案更新可能的新答案。即使得当前维护的集合内一定有全局最优解,通过全局最优解更新维护的集合并保证全局最优解一定在当前维护的集合中。

Luogu P1631 序列合并

题意:给定两个长为 \(n\) 的不降数列 \(a, b\),在它们中各取一个数可以得到 \(n^2\) 个和,求最小的 \(n\) 个。\(1 \leqslant n \leqslant 10^5, 1 \leqslant a_i, b_i \leqslant 10^9\)

发现 \(a_1 + b_1\) 一定是最小的,先将 \(a_1 + b_1\) 加入优先队列,每次弹出最小元素 \(a_i + b_j\),然后将下一次可能成为最小值的 \(a_{i + 1}, b_j\)\(a_i + b_{j + 1}\)\(a_{i + 1} + b_{j + 1}\) 入队。于是队列中元素被控制在 \(O(n)\) 级别,时间复杂度 \(O(n \log n)\),可以通过。

Luogu P2048 [NOI2010] 超级钢琴

题意:给定长为 \(n\) 的数列 \(a\),求长度在 \(L\)\(R\) 之间的子串的和的前 \(k\) 大值的和。\(1 \leqslant n, k \leqslant 5 \cdot 10^5, -10^3 \leqslant a_i \leqslant 10^3, 1 \leqslant L \leqslant R \leqslant n\),保证存在满足要求的子串。

处理前缀和数组 \(f\),题目即为求前 \(k\) 大的 \(f_j - f_i\)(这里用 \(i\) 代替了 \(i - 1\),便于处理)之和。

对每个位置 \(i \in [0, n - L]\),求出在 \([i + L, \min\{i + R, n\}]\) 中的 \(j\),使得 \(f_j\) 最大。这样得到的答案中一定包含全局最大的子串。

设状态 \(\{o, t, l, r\}\) 表示子串的起点为 \(o\),终点在 \([l, r]\) 之间选择,选择 \(t\) 为终点时取到最大值。

初始会将 \(\{o, t, o + l, \min\{o + R, n\}\} (o \in [0, n - L])\) 入队。每次提取出一个状态 \(\{o, t, l, r\}\) 后,将(如果合法)\(\{o, t', l, t - 1\}\)\(\{o, t'', t + 1, r\}\) 入队。

于是优先队列中的元素被控制在 \(O(n + k)\) 级别,最大值用 ST 表求,可以通过。

Luogu P5283 [十二省联考 2019] 异或粽子

题意:给定长为 \(n\) 的数列 \(a\),求子串的异或和的前 \(k\) 大值的和。\(1 \leqslant n \leqslant 5 \cdot 10^5, 1 \leqslant k \leqslant 5 \cdot 10^5, 0 \leqslant a_i \leqslant 4294967295\),保证存在满足要求的子串。

处理前缀异或和数组 \(f\),题目即为求前 \(k\) 大的 \(f_j \oplus f_i\)(这里用 \(i\) 代替了 \(i - 1\),便于处理)之和。

对每个位置 \(i \in [0, n - 1]\),求出在 \([i + 1, n]\) 中的 \(j\),使得 \(f_j \oplus f_i\) 最大。这样得到的答案中一定包含全局最大的子串。

设状态 \(\{o, t, l, r\}\) 表示子串的起点为 \(o\),终点在 \([l, r]\) 之间选择,选择 \(t\) 为终点时取到最大值。

初始会将 \(\{o, t, o + 1, n\} (o \in [0, n - 1])\) 入队。每次提取出一个状态 \(\{o, t, l, r\}\) 后,将(如果合法)\(\{o, t', l, t - 1\}\)\(\{o, t'', t + 1, r\}\) 入队。

于是优先队列中的元素被控制在 \(O(n + k)\) 级别,最大异或和用 0-1 Trie 求,可以通过。

CodeForces 241B Friends

本题因为 \(m\) 很大,不能套用前文所述的解法。

换一种思路:考虑把 \(a_i\) 从高位到低位插入 0-1 Trie 之后,二分第 \(m\) 大,通过第 \(m\) 大求答案。

对于二分的一个值 \(x\),枚举每个位置 \(i\),在 0-1 Trie 上找与 \(a_i\) 异或值大于等于 \(x\) 的值的个数。

类比求最大异或和的过程,考虑搜索到第 \(j\) 位。如果 \(x\) 的第 \(j\) 位为 \(1\),为了最终异或值大于等于 \(x\),可能的数一定在与 \(a_i\) 的第 \(j\) 位相异的子树中,递归即可;反之,如果 \(x\) 的第 \(j\) 位为 \(0\),与 \(a_i\) 的第 \(j\) 位相异的子树中的值一定全部满足条件,递归与 \(a_i\) 的第 \(j\) 位相同的子树即可。

于是可以在 \(O(n \log^2 w)\) 的时间内找到第 \(m\) 大的异或值(\(w\) 为值域,后文同),设这个值为 \(k\)


下一步是求前 \(m\) 大两两异或值的和。

容易想到,类似前文所述,只需要处理被计算的完整的子树与 \(a_i\) 的异或值的和。(即搜索时找到的 \(k\) 的第 \(j\) 位为 \(0\),与 \(a_i\) 的第 \(j\) 位相异的子树)直接对这些子树的根节点打标记,整体遍历一次 0-1 Trie 时容易得到这棵子树内每一位上 \(0\)\(1\) 的数量,答案也就容易统计了。

至多有 \(n \log w\) 个标记,处理每个标记需要枚举 \(\log w\) 位。同时,至多合并 \(O(n \log w)\) 次,单次合并的时间为 \(O(\log w)\)。综上,时间复杂度 \(O(n \log^2 w)\)


将两部分拼起来就得到了最终做法,时间复杂度 \(O(n \log^2 w)\),可以通过。

Code

Luogu P1631 序列合并

Luogu P2048 [NOI2010] 超级钢琴

Luogu P5283 [十二省联考 2019] 异或粽子

CodeForces 241B Friends

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/786771.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

别样的ABC大战

前言:BYD ABC 大战。此事发生于2024年3月,为保护隐私(有的人应该能看出来哈哈),人物名字均使用字母代替。故事虽根据真实事件改编,但较为夸张。 一天,W老师给我发来微信。她说:“你敢不敢和其他人举行ABC大战?”我豪爽的答应了:“我当然敢!”周六下午在花园路XX号举…

【NextJS】中间件实战介绍

原创 洞窝技术使用 Next.js 中间件实现高性能个性化 在当今的数字时代,用户期望获得量身定制的在线体验。个性化已经从一个奢侈品变成了必需品,尤其是对于希望在竞争激烈的市场中脱颖而出的企业来说。然而,实现高性能的个性化往往是一个挑战,需要在用户体验和系统性能之间取得…

排列组合问题

排列公式 从 \(n\) 个数中选出 \(m\) 个数并且排序。 公式推导: \[ A^2_3 = 3 \times 2 = 6\\3_6 = 6 \times 5 \times 4 = 120\\ A^2_6 = 6 \times 5 = 30\\ \therefore A^m_n = n(n-1)(n-2)\dots (n-m+1)\\ 又\because n!=n\times (n-1)\times (n-2) \dots \times 2\times…

Docker简介及安装

本系列将会与大家分享 Docker 的相关知识。本章主要简要介绍 Docker,并指导大家如何在 CentOS 7 上进行 Docker 的安装。本系列将会与大家分享 Docker 的相关知识。本章主要简要介绍 Docker,并指导大家如何在 CentOS 7 上进行 Docker 的安装。废话不多说,下面我们直接进入主…

C程序设计语言(第2版新版)练习题1-9

练习1-9 编写一个将输入复制到输出的程序,并将其中连续的多个空格用一个空格代替。#include <stdio.h>int main(int argc, char *argv[]) {(void)argc;(void)argv;int c;int c_last = \0;while((c = getchar()) != EOF) {if (( != c) || ( != c_last)) {putchar(c);}c…

C# .NET CORE 知识点总结【基础篇】

心之所向,勇往直前!记录面试中的那些小事。面试题只是一道门,最好还是走进屋里看看。正文 结语本篇到此结束,如果有任何疑问或者指正,请发表在评论区。

相遇(容斥+最短路+分类,水紫)

第5题 相遇 查看测评数据信息给定一个有n个节点m条边的无向图,在某一时刻节点st上有一个动点a, 节点end上有一个动点b, 动点a向节点end方向移动,要求是尽快到达end点,与此同时,动点b向节点st方向移动,要求是尽快到达st点, 但是整个过程中a和b不能相遇,问两点不相遇一…

NYX靶机笔记

NYX靶机笔记 概述 VulnHub里的简单靶机 靶机地址:https://download.vulnhub.com/nyx/nyxvm.zip 1、nmap扫描 1)主机发现 # -sn 只做ping扫描,不做端口扫描 nmap -sn 192.168.84.1/24 # 发现靶机ip为 MAC Address: 00:50:56:E0:D5:D4 (VMware) Nmap scan report for 192.168.…

VS2022 Visual Studio Installer 一直卡在0%,或者下载速度慢的问题解决办法

vs2022 installer,安装失败的问题C:\Users\Administrator\AppData\Local\Temp到c盘查看日志,发现是下载一个叫 vs_installer.opc的东西失败了,直接复制日志里的https://aka.ms/vs/17/release/installer,下载,发现成功下载,然后放到installer安装器同级目录,重新打开setu…

[Java基础]虚拟线程

虚拟线程(Virtual Thread)是 JDK 而不是 OS 实现的轻量级线程(Lightweight Process,LWP),由 JVM 调度。许多虚拟线程共享同一个操作系统线程,虚拟线程的数量可以远大于操作系统线程的数量。 虚拟线程和平台线程有什么关系? 在引入虚拟线程之前,java.lang.Thread 包已经…