Public NOIP Round #6 D 排序 题解

news/2024/11/19 16:29:03/文章来源:https://www.cnblogs.com/Scarab/p/18555072

Description

今天是 YQH 的生日,她得到了一个 \(1\sim n\) 的排列作为礼物。
YQH 是一个有强迫症的女孩子,她希望把这个排列从小到大排序,具体的,她可以进行这样的操作:

  • \([1,n]\) 分成若干个区间,假如是 \(m\) 段,依次为 \([l_1,r_1],[l_2,r_2],\dots,[l_m,r_m]\),其中 \(l_1=1,r_m=n,l_{i+1}=r_i+1,l_i\le r_i\)

  • 假如原来的排列为 \(a_{1,\dots,n}\),那么把排列变为 \(a_{l_m},a_{l_m+1},\dots,a_{r_m},a_{l_{m-1}},a_{l_{m-1}+1},\dots,a_{r_{m-1}},\dots,a_{l_1},a_{l_1+1},\dots,a_{r_1}\),即把每一段看作一个整体,然后把这个排列进行 reverse。
    YQH 希望进行尽可能少的操作,把序列从小到大排序。但是她太笨了,所以她找到你帮忙。注意,你不需要得到最小操作数。

\(n\leq 2\times 10^4\),次数限制为 \(90\)

Solution

考虑分治。

假设当前已经让 \(a_{[l,r]}\) 的数值域变成 \([l,r]\) 了,设 \(mid=\left\lfloor\frac{l+r}{2}\right\rfloor\),将 \(a_i\leq mid\) 视作 \(0\),否则视作 \(1\),现在需要将这个 \(01\) 序列排序,使得所有 \(0\) 都在 \(1\) 之前。

先把连续段缩掉,那么序列变为 \(10101\ldots 010\),考虑以 \(1,2,1,2\ldots\) 分段,则操作后变为 \(1000111000\ldots\),连续段数变为原来的 \(\frac{1}{3}\),所以将长度为 \(n\)\(01\) 序列排序的次数为 \(O(\log_3 n)\)

那么设 \(f(n)\) 表示将普通序列排序的次数,用上面的方式排序可以得到:

\(f(n)=f\left(\left\lceil\frac{n}{2}\right\rceil\right)+O(\log_3 n)\)

于是总次数为 \(1+\sum\limits_{j=0} \left\lceil\log_3\left(\left\lceil\frac{n}{2^j}\right\rceil\right)\right\rceil\),能过。

Code

#include <bits/stdc++.h>// #define int int64_tusing vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;const int kMaxN = 2e4 + 5;int n, m;
int a[kMaxN], len[kMaxN];
bool b[kMaxN], op[kMaxN];void prework(int l, int r) {int lst = l - 1;m = 0;for (int i = l; i <= r; ++i) {if (i == r || b[i] != b[i + 1]) {op[++m] = b[i], len[m] = i - lst;lst = i;}}
}vvi getvec(int l, int r) {vvi vec;for (;;) {prework(l, r);if (m == 2 && op[1] == 0 && op[2] == 1) break;std::vector<int> v;for (int i = 1, now = 1; i <= m; now = 3 - now) {now = std::min(now, m - i + 1);int s = 0;for (int j = i; j <= i + now - 1; ++j) s += len[j];v.emplace_back(s);i += now;}vec.emplace_back(v);int now = l;std::reverse(a + l, a + 1 + r);std::reverse(b + l, b + 1 + r);std::reverse(v.begin(), v.end());for (auto x : v) {std::reverse(a + now, a + now + x);std::reverse(b + now, b + now + x);now += x;}}return vec;
}vi merge(vi a, vi b) {vi c;for (auto x : a) c.emplace_back(x);for (auto x : b) c.emplace_back(x);return c;
}vvi solve(int l, int r) {if (l == r) return {};int mid = (l + r) >> 1;if (r - l + 1 > 3 && (~(l + r) & 1)) ++mid;for (int i = l; i <= r; ++i) b[i] = (a[i] > mid);auto vec = getvec(l, r), L = solve(l, mid), R = solve(mid + 1, r);int sz = std::max(L.size(), R.size());if (sz & 1) ++sz;L.resize(sz, vi{mid - l + 1});R.resize(sz, vi{r - mid});for (int i = 0; i < sz; ++i) {if (~i & 1) vec.emplace_back(merge(L[i], R[i]));else vec.emplace_back(merge(R[i], L[i]));}return vec;
}void dickdreamer() {std::cin >> n;for (int i = 1; i <= n; ++i) std::cin >> a[i];auto res = solve(1, n);std::cout << res.size() << '\n';for (auto &vec : res) {std::cout << vec.size() << ' ';for (auto x : vec) std::cout << x << ' ';std::cout << '\n';}
}int32_t main() {
#ifdef ORZXKRfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
#endifstd::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);int T = 1;// std::cin >> T;while (T--) dickdreamer();// std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";return 0;
}

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

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

相关文章

DHCP介绍与实现方法

简介:动态主机配置协议(Dynamic Host Configuration Protocol,缩写:DHCP)是 RFC 1541(已被 RFC 2131 取代)定义的标准协议,该协议允许服务器向客户端动态分配 IP 地址和配置信息。 工作原理: DHCP协议支持C/S(客户端/服务器)结构,主要分为两部分: 1、DHCP客户端:…

推荐一个好用的 REST API 测试工具 Apifox

大家好啊!今天给大家安利一个超级好用的 REST API 测试工具 —— Apifox。说实话,作为一个经常和 API 打交道的开发者,以前总是被各种 API 测试和管理的问题困扰。直到遇到了 Apifox,才发现原来 API 测试可以这么舒服! Apifox 是啥? 简单来说,Apifox 就是一个"一站…

Qwen2.5-0.5B-Instruct搭建

模型地址 https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct简介 通义千问新一代开源模型Qwen2.5,旗舰模型Qwen2.5-72B性能超越Llama 405B,再登全球开源大模型王座。Qwen2.5全系列涵盖多个尺寸的大语言模型、多模态模型、数学模型和代码模型,每个尺寸都有基础版本、指令跟…

Pod环境安装(Mac)

原文链接:https://blog.csdn.net/huwan12345/article/details/135088993 背景知识: 安装pods需要依赖 ruby 环境,而安装 ruby 需要借助能够管理不同版本的 ruby工具 rvm,安装 rvm 又需要借助工具 Homebrew,Homebrew是一款Mac OS平台下的软件包管理工具,拥有安装、卸载、更…

CI配置项,IT服务的关键要素

随着现今数字经济的不断发展,逐渐成熟的IT 基础设施已不再是简单的竞争优势,而已成为企业生存和发展的基石。然而,仅仅拥有强大的基础设施是不够的。为了保障 IT 服务的平稳运行和持续交付,企业还需要重点关注 IT 服务的核心构建模块——配置项(Configuration Item,CI)。…

类的组合、继承、模板类、标准库

任务2 GradeCalc.hpp1 #include <iostream>2 #include <vector>3 #include <string>4 #include <algorithm>5 #include <numeric>6 #include <iomanip>7 8 using std::vector;9 using std::string;10 using std::cin;11 using std::cout;1…

cmu15545笔记-查询优化(Query Optimization)

目录概述Heuristics / RulesCost-based SearchSingle relationMutiple relationGenertive / Bottom-UpTransformation / Top-DownNested sub-queriesDecomposing QueriesExpression/Queries RewritingStatistics 概述 数据库系统的执行流程:从优化器到磁盘所设计的步骤:查询优…

构建企业级数据分析 Agent:架构设计与实现

引言 数据分析 Agent 是现代企业数据栈中的重要组件,它能够自动化数据分析流程,提供智能化的数据洞察。1. 数据处理工具链设计 数据处理工具链是整个分析系统的基础设施,它决定了系统处理数据的能力和效率。一个优秀的工具链设计应该具备:良好的可扩展性:能够轻松添加新的数据…

空间计算、物理计算、实时仿真与创造拥有「自主行为」的小狗 | 播客《编码人声》

「编码人声」是由「RTE开发者社区」策划的一档播客节目,关注行业发展变革、开发者职涯发展、技术突破以及创业创新,由开发者来分享开发者眼中的工作与生活。虚拟世界与现实世界的界限逐渐模糊,已然成为不争的事实。但究竟哪些曾经的幻想已然照进现实,又有哪些挑战依然横亘眼…

ABB机械手维修-运动控制

ABB机械手运动控制ABB机械手的运动控制主要通过其先进的控制系统实现。ABB机械手具有多种运动模式,包括单轴运动、线性运动和重定位运动。在进行手动操纵前,需要将工作模式档位切换至手动减速模式。 - 单轴运动:也称为关节运动,是对机器人的各个关节轴进行单独控制移动操作…

不可思议!7、8 年外包进了国企!!

大家好,我是R哥。 今天分享一个非常「难以置信」的辅导案例,一个「双非二本」的兄弟从毕业就开始干外包,一直干了 7、8 年外包,从外包离职后,经过我们几个月的面试辅导,最终去了某国企,还是待遇最好的 10 家国企之一。 这兄弟是 5 月份加入面试辅导的,距离他离职已经个…

制造业怎么用好仓库管理系统?仓库管理系统在制造业中的应用实例

随着科技的发展,制造企业对仓库管理的要求也越来越高。大家都在想,怎么能用智能化、自动化的方法来提高仓库的工作效率,减少库存积压,同时让客户更满意。这可是企业发展的一个很关键的问题。这篇文章会通过几个实际的例子,详细讲讲WMS在制造业里是怎么发挥作用的。目的就是…