[USACO18OPEN] Out of Sorts P 题解

news/2025/2/8 20:18:53/文章来源:https://www.cnblogs.com/XuYueming/p/18705237

前言

题目链接:洛谷。

其他题解十分生硬地给出了 t[] 的定义,本题解按照解题思路,层层递进,自然得出题目解法。

题意简述

以下是冒泡排序的一轮:

void bubble_sort(int val[], int l, int r) {for (int i = l; i < r; ++i)if (val[i] > val[i + 1])swap(val[i], val[i + 1]);
}

定义 \((p, p+1)\)\(\{a_n\}\) 的一个「分割点」当 \(\max\limits_{i=1}^{p}a_i\leq\min\limits_{i=p+1}^na_i\)

以下是一个基于分治和冒泡排序的排序算法:

void qsort(int val[], int l, int r){if (l == r) return;do {bubble_sort(val, l, r);work_cnt += r - l + 1;} while (!check(val, l, r));// check(val, l, r) 返回 val[l~r] 中是否存在「分割点」divide_and_qsort_each_piece(val, l, r);// 将 val[l~r] 按照「分割点」分割成若干子问题,并递归调用 qsort
}

给你长度为 \(n\) 的序列 \(\{a_n\}\),求运行 qsort(a, 1, n) 后,全局变量 work_cnt 的值。

\(n \leq 10^5\)

题目分析

显然我们需要分析冒泡排序的性质。

一轮冒泡排序后,肯定会产生一个「分割点」。这是由于一轮冒泡排序后,序列中的最大值被冒泡到了最右侧,所以产生了一个「分割点」。所以那个 do...while 实际没有用处。

然后发现整个序列在排序过程中比较鬼畜,难以发现性质。于是考虑转变计数视角,求每一个元素被 bubble_sort 了多少次,答案就是每个元素答案之和。

对于一个元素,只要它没有到达最终位置,它会一直被 bubble_sort,这在时间轴上体现为一段前缀,我们只要求出在什么时候这个元素不会被 bubble_sort 即可。发现,每个元素唯一的递归出口 l == r 的实际含义为,该元素左右两侧都出现了「分割点」,于是问题似乎可以被进一步规约到每一个「分割点」出现的时刻。

一个「分割点」出现,当该在它左侧的元素都在它左侧,该在它右侧的元素都在它右侧了。这么想是因为我们冒泡排序的经典思考方式,关注于每一个元素的移动。我们有一个经典结论:

经典结论:

对于一个元素,倘若它想要向左移动,它在一轮冒泡中会恰向左移动一个位置。

考虑在一轮冒泡中,它会且只会和其左侧的最大值 swap,然后向左移动一个位置。

所以我们考虑在某一个「分割点」右侧的元素,什么时候到这个「分割点」左侧。所需的冒泡轮数,根据我们的结论,就是它到「分割点」的距离。那么对于所有在它右侧且想要跑到它左侧的元素,求出位置最靠右的元素的位置,即可求出这个「分割点」出现的时间。

接下来随便求了。给出一种可能的实现方式:设 \(b_i\) 表示排序后的序列 \(a'\) 的第 \(i\) 个元素 \(a'_i\) 为原序列 \(a_{b_i}\),再设 \(\operatorname{mxR}_i\) 表示 \(1\sim i\) 中,目标位置最右在哪里。那么 \(t_i=\operatorname{mxR}_i-i\) 就是「分割点」\((i, i+1)\) 出现的时刻。倘若其值小于 \(1\),说明该「分割点」一开始便存在,对 \(1\)\(\max\) 即可。答案根据我们的分析为 \(\sum\limits_{i=1}^n\max\{t_{i-1},t_i\}\),其中 \(t_0=1\)\(b_i\) 排序以下即可,很好求,不难发现 \(\operatorname{mxR}_i\) 即为 \(b_i\) 的前缀最大值。

时间复杂度 \(\mathcal{O}(n\log n)\),瓶颈在于一开始的排序。

代码

实际实现起来很短。

#include <cstdio>
#include <algorithm>
using namespace std;const int N = 100010;int n, a[N], b[N], t[N];
long long ans;signed main() {scanf("%d", &n);for (int i = 1; i <= n; ++i) {scanf("%d", &a[i]);b[i] = i;}sort(b + 1, b + n + 1, [] (int x, int y) -> bool {if (a[x] == a[y]) return x < y;  // notice this detailreturn a[x] < a[y];});t[0] = 1;for (int i = 1; i <= n; ++i) {b[i] = max(b[i], b[i - 1]);  // mxR[i]t[i] = b[i] - i;if (t[i] <= 0) t[i] = 1;}for (int i = 1; i <= n; ++i)ans += max(t[i], t[i - 1]);printf("%lld", ans);return 0;
}

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

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

相关文章

2.8 系统基本完成

今天将系统进行完善并通过了测试。 部分界面:数据库成功插入:在测试过程中遇到了一个问题:数据库中查到的某些元素无法正确传递(即为null值),在多次检查测试后发现是命名格式问题(我的程序主要是因为名字中带了“_”符号),在传递过程中无法识别,导致值出现错误,这让…

探索5款强大的报表软件:助力企业决策和数据分析

概述: 随着数据分析和决策的重要性不断提升,报表软件已经成为企业管理不可或缺的工具。报表软件能够将复杂的数据转化为直观的图表和报告,帮助管理层做出准确决策。以下是5款功能强大的报表软件,其中包括了山海鲸报表,每款软件都有其独特的优势,适用于不同的使用场景。 1…

1分钟学会DeepSeek本地部署,小白也能搞定!

DeepSeek 是国内顶尖 AI 团队「深度求索」开发的多模态大模型,具备数学推理、代码生成等深度能力,堪称"AI界的六边形战士"。 DeepSeek 身上的标签有很多,其中最具代表性的标签有以下两个:低成本(不挑硬件、开源) 高性能(推理能力极强、回答准确)一、为什么要…

内存占用与监控方式介绍

1.内存占用 神经网络模型常见的内存占用可以分为以下几个部分: 1.1 模型参数内存定义:神经网络的权重和偏置等参数会占用内存。 计算方法:参数总量 = 各层参数数量的总和。 每个参数的大小取决于数据类型(如 float32 为 4 字节,float16 为 2 字节,int8 为 1 字节)。公式…

WebGPU 版 Kokoro:浏览器端零成本使用高质量 TTS;苹果 ELEGNT 台灯机器人:赋予非人形机器人「情感」

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文章 」、「有看点的 会议 」,但内容仅代表编辑…

尝试使用阿里云计算巢部署 DeepSeek-R1

记录一下用阿里云计算巢部署 DeepSeek-R1 的经过。进入阿里云计算巢控制台的服务目录,选择 DeepSeek 社区版,点击「开始部署」,选择最便宜的 ECS 实例 GRID 虚拟化4核30G,费用是 1.748/小时。点击「立即创建」,然后控制台会显示正在部署的状态。部署完成后,控制台会显示公…

未来已来:云手机+AI如何重塑Facebook、Google的智能营销生态

未来已来:云手机+AI如何重塑Facebook、Google的智能营销生态 在数字化浪潮奔涌的当下,科技融合正以令人惊叹的速度重塑各个行业,智能营销领域更是首当其冲。云手机与AI自动化工具的深度融合,为Facebook、Google构建的庞大智能营销生态带来了颠覆性的变革,开拓出全新的发展…

Burp Suite 2024激活汉化

转载自https://blog.csdn.net/m0_52985087/article/details/140299827 前言在项目即将上线阶段,迈入生产环境之际,确保其安全性成为我们不可忽视的首要任务。为筑起一道坚不可摧的安全防线,我们借助业界公认的网络安全利器——Burp Suite,我们将展开一场全面的安全测试,旨…

清华权威出品!104页《DeepSeek从入门到精通》免费领,解锁AI时代的核心竞争力!

引言: 在AI技术席卷全球的今天,如何高效驾驭大模型工具已成为个人与企业脱颖而出的关键。清华大学新闻与传播学院新媒体研究中心元宇宙文化实验室余梦珑博士后团队倾力打造的《DeepSeek从入门到精通》电子书重磅发布!全书104页,从基础操作到高阶技巧,手把手教你玩转国产顶…

win11家庭中文版登录应用提示:“为了对电脑进行保护,已经阻止此应用”

1.家庭中文版组策略里面禁用:以管理员批准模式运行所有管理员 win11打不开组策略,需要复制文本内容到记事本,修改为bat后缀执行 @echo off pushd "%~dp0" dir /b c:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum …

4种比常见的线程池和线程同步买票问题

线程池 所谓的线程池:其实就是线程对象的容器。 可以根据需要,在启动时,创建1个或者多个线程对象。 java中有4种比较常见的线程池。 1.固定数量的线程对象。 2.根据需求动态创建线程:动态创建线程:根据需求来创建线程的个数,会自动给我们分配合适的线程个数来完成任务。 3.…