[Daimayuan] 排队(C++,逆序数)

news/2024/5/17 17:26:57 标签: c++, 算法, 逆序数, 归并排序

古老的星球上有这样一群人,他们每年都会参加盛大的周年庆。在进入场地之前所有人在入口排成两队,每队人数都是 n n n 人,第一队第 i i i 人身高为 a i a_i ai,第二队第 i i i 人身高为 b i b_i bi

人们在排队时,喜欢跟另一队相同位置的伙伴亲切地交谈。但是如果这两人身高相差太多,他们会感到有些尴尬,两人的尴尬指数 g i g_i gi 与身高差呈这样一种关系: g i = ( a i − b i ) 2 g_i=(a_i−b_i)^2 gi=(aibi)2

为了尽可能减轻尴尬,每队的人都可以与前后相邻者交换位置,次数不限,但只能在同队范围内交换。问最少需要交换多少次位置,可以使得总体尴尬度 ∑ ( a i − b i ) 2 \sum{(a_i−b_i)^2} (aibi)2 最小。如果答案太大,请输出这个最少交换次数对 1 0 8 − 7 10^8−7 1087 取模的结果。

保证每队人的身高两两不同。

输入格式

输入共三行。第一行是一个正整数 n n n,表示每队的人数。 第二行有 n n n 个整数,每两个整数用一个空格隔开,表示第一队人们的身高。 第三行有 n n n 个整数,每两个整数用一个空格隔开,表示第二队人们的身高。

输出格式

一个整数,表示最少的交换次数。

数据范围

1 ≤ n ≤ 1 0 5 , 0 ≤ a i , b i < 2 31 1≤n≤10^5,0≤a_i,b_i<2^{31} 1n105,0ai,bi<231,保证每队人们的身高各不相同

输入样例

4
2 3 1 4
3 2 1 4

输出样例

1

样例解释

只需交换第一队前两人,或者交换第二队前两人。这样人们都跟与自己身高相同的伙伴交谈,总体尴尬度为 0 0 0,即最小。

解题思路

题意规定尴尬指数的计算公式为 g i = ( a i − b i ) 2 g_i=(a_i−b_i)^2 gi=(aibi)2,而我们可以看出 ∑ i = 1 n g i \sum_{i=1}^{n}{g_i} i=1ngi的和中 ∑ a i 2 + b i 2 \sum a_i^2+b_i^2 ai2+bi2这部分是保持不变的,所以要使尴尬指数最小,只需要使 ∑ a i ∗ b i \sum a_i*b_i aibi最小。

根据公式 ( a i + b i ) 2 ≥ 2 ∗ a i ∗ b i ( a i = b i (a_i+b_i)^2 \ge 2*a_i*b_i(a_i=b_i (ai+bi)22aibi(ai=bi时等式成立 ) ) )可以看出,我们只需要使得任意两个人的身高尽可能的接近就可以了。

直观来讲,就是当两个队列都是单调递增的时候,尴尬指数最小。但是题目要求交换次数最小,那么我们就需要把一个队列的顺序转化为另外一个队列的顺序。

求最小相邻交换次数,就是求逆序数

这里简单介绍一下逆序数

对于序列 15234 15234 15234,指定标准为升序排序(也可以为降序)。那么 1 1 1的的逆序数就是在它的前面,比它大的数(不符合升序),这里显然是 0 0 0;通过计算, 5 , 2 , 3 , 4 5,2,3,4 5,2,3,4逆序数分别为 0 , 1 , 1 , 1 0,1,1,1 0,1,1,1,那么整个序列的逆序数 3 3 3(累加)。

显然两个队列都是没有顺序的。但是没关系,我们不需要值有顺序,只需要索引有顺序就可以了。

我们将一个元素的值转换为它需要对应元素的索引,这样就可以计算逆序数了(将转换后的序列重新变为升序排序)。

计算逆序数的方法通常是归并排序(这里不做介绍,只是简单给出实现)。

最后,AC代码如下:

#include <iostream>
#include <algorithm>
using namespace std;
const int max_n = 1e5;
const long long mod_num = 1e8 - 7;

struct node { int idx, val; } a[max_n], b[max_n];
long long ans = 0;
int temp[max_n];

void merge_sort(node arr[], int l, int r) {
	if (l == r) return;

	int m = l + r >> 1;
	merge_sort(arr, l, m);
	merge_sort(arr, m + 1, r);

	long long i = l, j = m + 1, k = l;
	while (i <= m && j <= r) {
		if (arr[i].val > arr[j].val) {
			temp[k] = arr[j].val;
			j++, k++;
			ans = (ans + m - i + 1LL) % mod_num;//累计逆序数
		}
		else {
			temp[k] = arr[i].val;
			i++, k++;
		}
	}

	while (i <= m) temp[k++] = arr[i++].val;
	while (j <= r) temp[k++] = arr[j++].val;
	for (i = l; i <= r; i++) arr[i].val = temp[i];
}

int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		//scanf("%d", a + i);
		cin >> a[i].val;
		a[i].idx = i;
	}
	for (int i = 0; i < n; i++) {
		//scanf("%d", b + i);
		cin >> b[i].val;
		b[i].idx = i;
	}

	sort(a, a + n, [](node n1, node n2) {
		return n1.val < n2.val;
		});
	sort(b, b + n, [](node n1, node n2) {
		return n1.val < n2.val;
		});

	for (int i = 0; i < n; i++) {
		a[i].val = b[i].idx;
	}
	sort(a, a + n, [](node n1, node n2) {
		return n1.idx < n2.idx;
		});

	merge_sort(a, 0, n - 1);
	cout << ans << endl;
	return 0;
}


http://www.niftyadmin.cn/n/257663.html

相关文章

分布式文件系统HDFS的多问多答

分布式文件系统HDFS 简述HDFS的优缺点简述HDFS的体系结构请论述HDFS中SecondaryNameNode的作用和工作原理请论述HDFS写数据原理 简述HDFS的优缺点 HDFS的优良特性&#xff1a; ①兼容廉价的硬件设备。在成百上千台廉价服务器中存储数据&#xff0c;常会出现节点失效的情况&…

Ubuntu Windows (宿主机)和 Linux 文件互传

目标&#xff1a; 我想把在本地下载的Pycharm 上传至 Ubuntu 环境中&#xff0c;然后在Ubuntu上安装pycharm&#xff0c;谈到为什么使用Ubuntu &#xff0c;因为这个对新手学习linux 环境比较友好&#xff0c;centos 比较麻烦当然你也能学到很多东西。 方式&#xff1a;经过上…

centos8 编译安装postgresql15.2

1. 下载源码 从 https://www.postgresql.org/ftp/source/ 下载源码postgresql-15.2.tar.gz 到 /root/soft 2. 准备编译环境 首先把自动创建的postgres用户删除&#xff0c; 命令如下&#xff1a; userdel -r postgres然后把用户postgres的HOME目录建在“/home”目录下&…

java的validation框架(参数校验)

一.bean validation和hibernate validator参数校验常用约束注解&#xff1a; 空值校验类&#xff1a;Null&#xff0c;NotNull&#xff0c;NotEmpty&#xff0c;NotBlank等 范围校验类&#xff1a;Min&#xff0c;Size&#xff0c;Digits&#xff0c;Future&#xff0c;Negati…

使用Python和Flask创建URL短链接

大家好&#xff0c;使用 Python Flask 创建 URL 缩短器是一个有趣而简单的项目&#xff0c;可以帮助您深入了解 Web 开发的世界。Flask 是 Python 的轻量级 Web 框架&#xff0c;可让您快速轻松地构建 Web 应用程序。在本文中&#xff0c;我们将介绍使用 Flask 构建基本 URL 缩…

Linux下获取线程id的方法总结

方法总结说明 getpid() Linux系统调用&#xff0c;获取进程id&#xff0c;也是主线程id。 gettid() Linux系统调用&#xff0c;获取线程id。 C运行库没有封装这个接口…用syscall()方式调用。 在主线程中&#xff0c;getpid gettid。 syscall(SYS_gettid) 直接调用Linux系统…

HNU-计算机系统-讨论课5

WARNING&#xff1a; 本题为开放性题目&#xff0c;所设计的也仅仅是一个可能的模型而已&#xff0c;再考虑到个人水平有限。在呈现效果上难免会有缺漏以及可行性的缺陷。故请批判性地接收&#xff01; 所以如果知识有错误或者缺漏&#xff0c;请一定要指出&#xff0c;您的建…

deepstream的nvv4l2h264enc硬编码插件讲解,实现rtsp推流,且无延迟

nvv4l2h264enc插件可以接收NV12格式的输入。在NV12格式下&#xff0c;Y和UV分量是分开存储的&#xff0c;且每个像素占用1.5个字节的存储空间。这种格式对于使用GPU进行硬件编码非常高效&#xff0c;因为GPU可以直接访问显存中的数据&#xff0c;而不需要进行复制操作。一般是经…