10.1考试T4(swap)题解

news/2025/10/1 21:49:21/文章来源:https://www.cnblogs.com/aceS0/p/19122922

题目描述

\(link\)

小 D 正在研究交换。

小 D 认为一个整数序列是好的,当且仅当它先(不严格)上升,后(不严格)下降。

形式化地,我们认为序列 \(𝑎_1,𝑎_2,...,𝑎_𝑛\) 是好的,当且仅当存在某个 \(𝑘∈[1,𝑛]\),使得对于任意
\(1 ≤𝑖 <𝑘\),有 \(𝑎_𝑖 ≤𝑎_𝑖+1\),且对于任意 \(𝑘≤𝑖<𝑛\),有 \(𝑎_𝑖 \ge 𝑎_𝑖+1\)

小 D 得到了一个长度为 𝑛 的序列 \(𝑎_1,𝑎_2,...,𝑎_𝑛\),他想让这个序列变成好的。

小 D 每次可以交换相邻的两个元素。因为交换很累,所以小 D 想知道,他最少需要交换多少次。

这下小 D 不会了,请你帮帮他。

subtask1(15pts):\(𝑛 ≤ 10\)

subtask2(20pts):\(𝑛 ≤ 500\)

subtask3(15pts):\(𝑛 ≤ 5000\)

subtask4(15pts):\(𝑛 ≤ 10^5\)

subtask5(20pts):\({𝑎}\) 是一个 \([1,𝑛]\) 的排列。

subtask6(15pts):无特殊限制。

对于 100% 的数据,\(1≤𝑛≤3×10^5,1≤𝑎_𝑖 ≤𝑛\)

方法

考虑贪心。

对于一个序列,如果我们要让他变好,其最小值一定会被移到最左边或最右边。移到最左边或最右边就取决于移到哪边需要的次数最少。

于是,我们再考虑分治。每次将对序列中最小的数移到最边上,给 \(ans\) 加上移动次数,并将这个数删掉。这样,我们就又得到了一个序列。对序列进行这样的重复操作,直到 \(n\) 个数全部被删除,输出 \(ans\) 即可。

但是,当我们有很多个并列最小的数时,对这些数删除的顺序是有讲究的。每次只能删除最左边或最右边的数,否则一定会产生两个相等的数交换位置的情况。这无疑是无意义的,会使答案不是最优。并且,应删除最左边或最右边中删除所需次数更少的一边。这样,才能保证后面被删除的数是最优的。

时间复杂度:\(O(n^2)\)

优化

观察到 \(n\) 最大能达到 \(3×10^5\)\(n ^ 2\) 是肯定卡不过去的。这时候我们便需要优化。

我们可以使用平衡树\(fhq-treap\)其实树状数组也可以用,又快又好些,吹普常数大的没边,但我是范浩强吹普死忠粉,我就要用。 维护 \(treap\) 对一个序列分成三段,一段为要删的数前的数,一段为其自己,一段为其后面的数,启动次数就是前面的数的 \(size\) 和后面的数的 \(size\)\(min\),然后再将前后的数合并,即将要删掉的数删掉。重复操作即可,细节看代码就行。我对我马蜂的美丽程度还是很自信的。

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define usd unsigned
#define el cout << '\n'
#define lowbit(x) (x & (-x))
const int ranmod = 1e7;
#define random ((rand() * rand()) % ranmod)
#define AC return 
#define AK return 0
#define YS cout << "YES"
#define NO cout << "NO"
#define Ys cout << "Yes"
#define No cout << "No"
#define ys cout << "yes"
#define no cout << "no"
#define ls(i) ch[i][0]
#define rs(i) ch[i][1]
#define debug(num) cerr << #num << ' ' << num << '\n'
// void init();
void main_();
signed main() {ios :: sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);// freopen(".in", "r", stdin);// freopen(".out", "w", stdout);int t = 1;// cin >> t;while(t--) {// init();main_();}AK;
}
const int mod = 95225987, maxn = 3 * 1e5 + 18;int ch[maxn][2], rnd[maxn], val[maxn], siz[maxn], tot, rt;
int add(int num) {tot++;ls(tot) = rs(tot) = 0;rnd[tot] = random;siz[tot] = 1;val[tot] = num;return tot;
}
void push_up(int i) {siz[i] = siz[ls(i)] + siz[rs(i)] + 1;
}
int merge(int l, int r) {if(l * r == 0) return l + r;int res = 0;if(rnd[l] < rnd[r]) {res = l;rs(l) = merge(rs(l), r);} else {res = r;ls(r) = merge(l, ls(r));}push_up(res);return res;
}
void split(int rt, int v, int &l, int &r) {if(rt == 0) {l = 0, r = 0; AC;}if(val[rt] <= v) {l = rt;split(rs(l), v, rs(l), r);push_up(l);} else {r = rt;split(ls(r), v, l, ls(r));push_up(r);}   
}
int show(int id) {int a, b, mid;split(rt, id, a, b);split(a, id - 1, a, mid);int res = min(siz[a], siz[b]);debug(siz[a]), debug(siz[b]);rt = merge(a, merge(mid, b));return res;
}
int del(int id) {int a, b, mid;split(rt, id, a, b);split(a, id - 1, a, mid);int res = min(siz[a], siz[b]);debug(siz[a]), debug(siz[b]);rt = merge(a, b);return res;
}int n, ans = 0;
map <int, deque <int> > a;void main_() {cin >> n;for(int i = 1; i <= n; i++) {int num;cin >> num;rt = merge(rt, add(i));a[num].push_back(i);}for(auto tmp : a) {while(!tmp.second.empty()) {if(tmp.second.size() == 1) {ans += del(tmp.second.front());tmp.second.pop_front();} else  {int l = show(tmp.second.front()), r = show(tmp.second.back());if(l <= r) {ans += del(tmp.second.front());tmp.second.pop_front();} else {ans += del(tmp.second.back());tmp.second.pop_back();}}}}cout << ans; el;
}

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

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

相关文章

如何在windows10的子系统(wsl)中安装php开发环境 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

学校网站建设经验介绍网络营销策划名词解释

Hi~ 大家好久不见呀&#xff01; 一直忙&#xff0c;但不知道在忙啥&#xff0c;好多事情都落下了&#xff0c;ERP的文章最近也没有时间更新&#xff0c;接下去我还在考虑弄个直播&#xff0c;不知道大家有没有什么想了解的&#xff0c;大家给我留言&#xff0c;直播的时候给…

抚顺网站开发3g微网站

当从键盘连续进行输入时用while&#xff0c;但是程序自己不会通过正常的输入结束。 scanf("%d%d",&a, &b); 如果a和b都被成功读入&#xff0c;scanf()的返回值是2 如果只有a被成功读入或者只有b被成功读入&#xff0c;scanf()的返回值为1 如果a和b都未被…

福州高端网站建设服务网络公司建设银行软件官方网站

目录 56. 合并区间 方法1&#xff1a;fff 看方法2&#xff1a;fff优化版 方法3&#xff1a; 738.单调递增的数字 968.监控二叉树&#xff08;贪心二叉树&#xff09; 56. 合并区间 判断重叠区间问题&#xff0c;与452和435是一个套路 方法1&#xff1a;fff 看方法2&am…

20251001 之所思 - 人生如梦

20251001 之所思 今年的生日恰好遇到了国庆,猛然间发现这也是自己最后以三开头的生日了;明年的今天就40岁了,有点恍惚,感觉最近的五年过的太快了,仿佛被偷走了一样 ...今天起的很早,希望自己接下来的一年都能早起…

app界面设计欣赏网站无锡高端网站设计制作

0. 简介 关于车辆的全景环视系统网上已经有很多的资料&#xff0c;然而几乎没有可供参考的代码&#xff0c;这一点对入门的新人来说非常不友好。全景环视系统&#xff0c;又称AVM。在自动驾驶领域&#xff0c;AVM属于自动泊车系统的一部分&#xff0c;是一种实用性极高、可大幅…

湘潭网站建设开发163企业邮箱服务器怎么设置

在产品的设计及生产过程中&#xff0c;经常会出现设计变更、工艺变更、制程调整、非计划停线及转产、转线等“变化”。 如何确保这些“变化”不影响产品后续的生产品质&#xff1f;这就需要在作业准备验证、停产后验证阶段&#xff0c;进行不能缺少的重要环节——“首件检验”。…

平面设计工作室网站专业的网页设计和网站建设公司

web压力测试工具webbench介绍 webbench最多可以模拟3万个并发连接去测试网站的负载能力&#xff0c;并发能力比较高&#xff0c;可以测试https及动态静态页面。 核心原理 父进程fork若干个子进程&#xff0c;每个子进程在用户要求时间或默认的时间内对目标web循环发出实际访问…

优必选 —— 人形机器人 —— 二次开发

优必选 —— 人形机器人 —— 二次开发本博客是博主个人学习时的一些记录,不保证是为原创,个别文章加入了转载的源地址,还有个别文章是汇总网上多份资料所成,在这之中也必有疏漏未加标注处,如有侵权请与博主联系。…

dns看国外网站建立免费个人网站

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 >出处&#xff1a; >https://www.fangzhipeng.com > 本文出自[方志朋的博客](http://blog.csdn.net/forezp) 本文为转载文章&…

GNS3环境下静态路由配置实例与分析(管理距离、度量值) - 教程

GNS3环境下静态路由配置实例与分析(管理距离、度量值) - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Co…

网站积分的作用京东app官网下载

目录 写在开头1. 电商平台流量概览1.1 流量来源的分类1.2 各流量来源的特性与价值 2. 流量来源的数据分析方法2.1 流量数据收集与整理2.2 流量质量评估指标2.3 流量转化路径分析 3. 流量来源优化策略3.1 提升自然搜索流量的SEO策略关键词优化内容优化技术优化示例&#xff1a;在…

ppt做杂志模板下载网站有哪些如何使用阿里云服务器建设网站

一、背景 应用持续访问又大又热的key&#xff0c;会造成Redis实例CPU高、流量被打满、数据在内存积压&#xff0c;甚至导致实例达到配额限制被oom-kill。在异步调用、pipeline、mget等批量调用场景比较常见。 大key分为两种情况 集合元素多且全量获取集合数据&#xff1a;命…

两级页表

单级页表存在什么问题,如何解决 问题一:页表必须连续存放,因此当页表很大时,需要占用更多个连续的页框 解决方法:为离散分配的页表再建立一张页表,称为页目录表(套娃) 问题二:进程在一段时间内只需要访问几个…

酒店网站建设目标网站建设 科目

目录 LeetCode之路——232. 用栈实现队列 分析&#xff1a; LeetCode之路——225. 用队列实现栈 分析&#xff1a; 栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;是两种基本的数据结构&#xff0c;它们在计算机科学中用于不同的目的。以下是它们的定…

复健。(10月,OI)

1 IAMOI 击倒了我。 P14113 [IAMOI R4] 彻底怒了 我草,P14113 彻底怒了。P14113 指出了最核心的矛盾点:如果你没有清空 cur 时忘记再加入处理的字符,怎么可能无法通过该题?这确实是我的严重错误。我需要彻底承认我…

免费字体设计网站邢台网站建设多少钱

做了很多种方法 1&#xff1a; 线程 thread的方法 2&#xff1a; backGroundWorker的方法 3&#xff1a; 自定义线程类 4&#xff1a; 做一个进度条的窗体 通过自定义设置做&#xff08;最方便快捷&#xff09; public partial class waitingProcessbar : Form{public waitin…

深圳凌 网站开发北京网站建设技术托管

package com.lbj.javase23; import java.io.*;public class ExceptionTest04 {public static void main(String[] args) throws FileNotFoundException{//使用throws处理异常不是真正处理异常而是推卸责任&#xff0c;谁调用就上抛给谁//上面的m1方法如果出现了异常&#xff0c…

实用指南:自动驾驶中的传感器技术55——USS(1)

实用指南:自动驾驶中的传感器技术55——USS(1)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas",…

市场交易反心理特征之三:日内假反转

过于惧怕大资金某一日的出货规模,而没注意大资金的后续意图 案例:2017年9月30日,10月23日和11月3日,京东方A。2017年9月30日,京东方A 2017年10月23日,京东方A2017年11月3日,京东方A 情况描述:在主力大出货后几…