牛客——火柴排队(树状数组与归并排、逆序对)

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai−bi)2\sum (a_i-b_i)^2∑(ai​−bi​)2
其中 ai 表示第一列火柴中第 i 个火柴的高度, bi 表示第二列火柴中第 i 个火柴的高度。
每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果。

输入描述:

共三行,第一行包含一个整数 n ,表示每盒中火柴的数目。
第二行有 n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。
第三行有 n 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。

输出描述:

一个整数,表示最少交换次数对 99,999,997 取模的结果。

一、归并排序的基本思想是将待排序的序列分成两个子序列,分别对两个子序列进行排序,然后将两个已排序的子序列合并成一个有序序列。通过递归地将序列分解成足够小的子序列,再将子序列两两合并,最终得到完全有序的序列。

归并排序的具体步骤如下:

  1. 分解(Divide):将待排序的序列不断二分,直到得到足够小的子序列。

  2. 解决(Conquer):对每个子序列进行排序,可以使用递归调用归并排序。

  3. 合并(Merge):将两个已排序的子序列合并成一个有序序列。合并操作中,需要创建一个临时数组来存储合并后的有序序列。

归并排序的时间复杂度是 O(nlogn),其中 n 是待排序序列的长度。它的排序过程是稳定的,即相等元素的相对顺序不会改变。

归并排序可以用于排序各种类型的数据,尤其适用于链表结构。相对于其他排序算法,归并排序的主要优点是在最坏情况下也能保证 O(nlogn) 的时间复杂度,因此在实际应用中被广泛使用。

合并的过程中,需要用到一个辅助数组来暂存合并后的有序数组。具体来说,假设待合并的两个有序数组分别为 A 和 B,它们的长度分别为 n 和 m,合并后的有序数组为 C,那么合并的过程可以按如下步骤进行:

1.定义三个指针 i、j 和 k,分别指向数组 A、B 和 C 的起始位置。

2.比较 A[i] 和 B[j] 的大小,将小的元素放入 C[k] 中,并将对应指针向后移动一位。

3.重复步骤 2,直到其中一个数组的元素全部放入 C 中。

4.将另一个数组中剩余的元素放入 C 中。

归并排序的优点是稳定性好,即对于相等的元素,在排序前后它们的相对位置不会改变。缺点是需要额外的空间来存储辅助数组。

二、逆序对是指在一个序列中,如果两个元素的顺序与它们在原序列中的顺序相反,即前面的元素大于后面的元素,则这两个元素构成一个逆序对。

例如,在序列 [2, 4, 1, 3, 5] 中,有三个逆序对:(2, 1),(4, 1),(4, 3),因为这些元素的顺序与它们在原序列中的顺序相反。

逆序对在排序算法中具有重要的意义,它可以衡量一个序列的有序程度。对于一个完全有序的序列,逆序对数为0,而对于一个完全逆序的序列,逆序对数最大。因此,逆序对可以用来评估一个序列的有序性。

在算法设计中,可以使用分治法来统计逆序对的数量。例如,可以使用归并排序算法,在归并的过程中统计逆序对的数量。具体来说,归并排序将序列分为两个子序列,然后分别对子序列进行排序,并在合并的过程中统计逆序对的数量。

代码:

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 5;
const int mod = 1e8 - 3;int n;
int c[N], tmp[N];struct Node {int data;int idx;
};bool cmp(Node x, Node y) {return x.data < y.data;
}int merge_sort(int l, int r) {if (l >= r) return 0;int mid = l + r >> 1;int res = (merge_sort(l, mid) + merge_sort(mid + 1, r)) % mod;int i = l, j = mid + 1, k = 1;while (i <= mid && j <= r) {if (c[i] <= c[j]) tmp[k++] = c[i++];else {res += mid - i + 1;tmp[k++] = c[j++];}}while (i <= mid) tmp[k++] = c[i++];while (j <= r) tmp[k++] = c[j++];for (int i = l, j = 1; i <= r; i++, j++) c[i] = tmp[j];return res % mod;
}int main() {cin >> n;Node a[N], b[N];for (int i = 1; i <= n; i++) {cin >> a[i].data;a[i].idx = i;}for (int i = 1; i <= n; i++) {cin >> b[i].data;b[i].idx = i;}sort(a + 1, a + 1 + n, cmp);sort(b + 1, b + 1 + n, cmp);for (int i = 1; i <= n; i++)c[b[i].idx] = a[i].idx;int ans = merge_sort(1, n);cout << ans % mod << endl;return 0;
}

具体解析看这个:刷题总结——火柴排队(NOIP2013)-CSDN博客

三、树状数组

树状数组(Binary Indexed Tree,BIT),也被称为 Fenwick 树,是一种用于高效计算前缀和的数据结构。它可以在 O(logn) 的时间复杂度内完成单点更新和前缀和查询操作。

树状数组主要用于解决频繁更新数组元素、频繁查询前缀和的问题,例如求逆序对、求区间和等。它的主要思想是将原始数组按照某种方式进行压缩,从而减少查询和更新操作的时间复杂度。

树状数组的核心是一个数组,通常用 BIT 表示。数组的下标从 1 开始,对应于原始数组的元素位置。数组的每个元素存储了一部分原始数组的元素和,具体的计算方式是通过二进制的技巧来实现的。

树状数组的基本操作包括单点更新和前缀和查询:

  1. 单点更新:通过不断修改 BIT 数组的某些元素,实现对原始数组中某个位置上元素的更新。更新操作的时间复杂度为 O(logn)。

  2. 前缀和查询:通过不断累加 BIT 数组的某些元素,实现对原始数组的前缀和计算。查询操作的时间复杂度为 O(logn)。

树状数组的构建过程相对简单,首先初始化 BIT 数组为全 0,然后通过单点更新操作依次更新 BIT 数组中的元素。构建完成后,即可进行前缀和查询。

树状数组的应用非常广泛,例如在求逆序对的问题中,可以使用树状数组来统计逆序对的数量;在求区间和的问题中,可以使用树状数组来快速计算任意区间的和。

首先不难想到a序列的第k小与b序列的第k小分别对应就能达到答案要求

将序列a,b做一些类似离散化的处理
先给序列中每个数标上编号,然后按原来的权值排序

这样a,b都变成了1-n的排列
现在问题可以转化为最少将b做多少次相邻元素的交换可以与a完全相同

我们设数组c[a[i]]=b[i]

若b数组与a数组完全相同,那么c[a[i]]=a[i]

即c[i]=i

代码如下:

#include <iostream>
#include <algorithm>#define int long long
using namespace std;const int N = 1e6 + 5, mod = 1e8 - 3;int n;
int c[N], tr[N];int lowbit(int x) {return x & -x;
}void add(int x, int c) {for (int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}int sum(int x) {int res = 0;for (int i = x; i; i -= lowbit(i)) res += tr[i];return res;
}signed main() {cin >> n;for (int i = 1; i <= n; i++) {int x;cin >> x;c[x] = i;}int res = 0;for (int i = 1; i <= n; i++) {int x;cin >> x;int idx = c[x];add(idx, 1);res += i - sum(idx);}cout << res % mod << endl;return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int NN = 1e5 + 4;
const int P = 99999997;
int n;
vector<int> a(NN), b(NN), c(NN);
int lower(int x) {return x & (-x);
}
void add(int x) {while (x) {c[x]++;x -= lower(x);}
}
int get(int x) {int sum = 0;while (x <= n) {sum += c[x];x += lower(x);}return sum;
}
int main() {cin>>n;for (int i = 1; i <= n; i++) {int x;cin>>x;a[x] = i;}for (int i = 1; i <= n; i++) {int x;cin>>x;b[i] = a[x];}int ans = 0;for (int i = 1; i <= n; i++) {ans = (ans + get(b[i] + 1)) % P;add(b[i]);}cout<<ans;return 0;
}

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

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

相关文章

力扣55. 跳跃游戏(动态规划)

Problem: 55. 跳跃游戏 文章目录 题目描述思路复杂度Code 题目描述 思路 我们将问题稍做转换每次求取当前位置可以走到的最远位置&#xff0c;在此基础上我们将最终判断是否能走出整个nums&#xff1b;同时我们要判断中途会不会遇到某个位置是0使得不能继续走下去 复杂度 时间…

企业资产|企业资产管理系统|基于springboot企业资产管理系统设计与实现(源码+数据库+文档)

企业资产管理系统目录 目录 基于springboot企业资产管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户信息管理 2、用户审核管理 3、资产分类管理 4、资产信息管理 5、资产信息添加 6、资产借出统计 7、资产归还审核 8、资产维修管理 9、资产维修…

Unity中的Lerp插值的使用

Unity中的Lerp插值使用 前言Lerp是什么如何使用Lerp 前言 平时在做项目中插值的使用避免不了&#xff0c;之前一直在插值中使用存在误区&#xff0c;在这里浅浅记录一下。之前看的博客或者教程还多都存在一个“永远到达不了&#xff0c;只能无限接近”的一个概念。可能是之前脑…

解线性方程组(一)——克拉默法则求解(C++)

克拉默法则 解线性方程组最基础的方法就是使用克拉默法则&#xff0c;需要注意的是&#xff0c;该方程组必须是线性方程组。 假设有方程组如下&#xff1a; { a 11 x 1 a 12 x 2 ⋯ a 1 n x n b 1 a 21 x 1 a 22 x 2 ⋯ a 2 n x n b 2 ⋯ ⋯ ⋯ a n 1 x 1 a n 2 x 2…

代码随想录Leetcode70. 爬楼梯

题目&#xff1a; 代码&#xff08;首刷自解 2024年2月19日&#xff09;&#xff1a; 空间复杂度为O(N)&#xff0c;如果想要优化空间复杂度&#xff0c;则只用三个变量进行状态转移也可以&#xff0c;参考 代码随想录 Leetcode509. 斐波那契数-CSDN博客 class Solution { pu…

Windows 重启 explorer 的正确做法

目录 一、关于 Restart Manager 二、重启管理器实例 三、完整实现代码和测试 本文属于原创文章&#xff0c;转载请注明出处&#xff1a; https://blog.csdn.net/qq_59075481/article/details/136179191。 我们往往使用 TerminateProcess 并传入 PID 和特殊结束代码 1 或者…

Repo命令使用实例(三十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

【Spring学习】Spring Data Redis:RedisTemplate、Repository、Cache注解

1&#xff0c;spring-data-redis官网 1&#xff09;特点 提供了对不同Redis客户端的整合&#xff08;Lettuce和Jedis&#xff09;提供了RedisTemplate统一API来操作Redis支持Redis的发布订阅模型支持Redis哨兵和Redis集群支持基于Lettuce的响应式编程支持基于JDK、JSON、字符…

ClickHouse监控及备份

第1章 ClickHouse监控概述 第2章 Prometheus&Grafana的安装 第3章 ClickHouse配置 第4章 Grafana集成Prometheus 第5章 备份及恢复

用户空间与内核通信(二)

文章&#xff1a;用户空间与内核通信&#xff08;一&#xff09;介绍了系统调用&#xff08;System Call&#xff09;&#xff0c;内核模块参数和sysfs&#xff0c;sysctl函数方式进行用户空间和内核空间的访问。本章节我将介绍使用netlink套接字和proc文件系统实现用户空间对内…

.NET Core WebAPI中使用Log4net记录日志

一、安装NuGet包 二、添加配置 // log4net日志builder.Logging.AddLog4Net("CfgFile/log4net.config");三、配置log4net.config文件 <?xml version"1.0" encoding"utf-8"?> <log4net><!-- Define some output appenders -->…

机器学习8-决策树

决策树&#xff08;Decision Tree&#xff09;是一种强大且灵活的机器学习算法&#xff0c;可用于分类和回归问题。它通过从数据中学习一系列规则来建立模型&#xff0c;这些规则对输入数据进行递归的分割&#xff0c;直到达到某个终止条件。 决策树的构建过程&#xff1a; 1.…

【知识整理】简述 Code Review - 代码审查

一、Code Review 简述 为保证上线代码质量&#xff0c;经研究决定0412版本起实行Code Review 。具体操作方式为组织 review 会。提出的优化点需立即执行更改&#xff0c;Review会要求给出调整方式方法。同时为了确保项目或迭代版本的时间&#xff0c;请各开发同学提前做好时间…

Linux系统安全:安全技术和防火墙

目录 一、安全技术和防火墙 1.安全技术 2.防火墙的分类 二、防火墙 1.iptables四表五链 2.黑白名单 3.iptables基本语法 4.iptables选项 5.控制类型 6.隐藏扩展模块 7.显示扩展模块 8.iptables规则保存 9.自定义链使用 一、安全技术和防火墙 1.安全技术 入侵检测系…

【PyQt】12-滑块、计数控件

文章目录 前言一、滑块控件 QSlider运行结果 二、计数器控件 QSpinBox运行结果 总结 前言 1、滑块控件 2、计数控件 一、滑块控件 QSlider #Author &#xff1a;susocool #Creattime:2024/2/15 #FileName:28-滑块控件 #Description: 通过滑块选择字体大小 import sys from PyQ…

【JavaEE】_HTTP请求首行

目录 1. URL 2. 方法 2.1 GET方法 2.2 POST方法 2.3 GET与POST的区别 2.4 低频使用方法 1. URL 在mysql JDBC中已经提到过URL的相关概念&#xff1a; 如需查看有关JDBC更多内容&#xff0c;原文链接如下&#xff1a; 【MySQL】_JDBC编程-CSDN博客 URL用于描述某个资源…

移动通信相关知识学习笔记

一、移动通信架构简图 移动无线的接入网是专指各种基站设备。核心网就是各种交换机。 二、无线信号基本原理 无线网络中&#xff0c;使用AP设备和天线来实现有线和无线信号互相转换。如上图所示&#xff0c;有线网络侧的数据从AP设备的有线接口进入AP后&#xff0c;经AP处理为…

代码随想录算法训练营第十八天|235.二叉搜索树的最近公共祖先,701.二叉搜索树中的插入操作,450.删除二叉搜索树节点

235.二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树节点 235.二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近…

基于shp数据制作3DTiles建筑白膜

经纬管网建模系统MagicPipe3D&#xff0c;本地离线参数化构建地下管网、建筑三维模型&#xff0c;输出标准3DTiles服务、Obj模型等格式&#xff0c;支持Cesium、Unreal、Unity、Osg等引擎加载进行三维可视化、语义查询、专题分析。欢迎下载试用&#xff1a;http://www.magic3d.…

Spring Boot 笔记 023 注册页面

1.1 request.js请求工具 //定制请求的实例//导入axios npm install axios import axios from axios; //定义一个变量,记录公共的前缀 , baseURL const baseURL /api; const instance axios.create({baseURL})//添加响应拦截器 instance.interceptors.response.use(result…