【一百零八】【算法分析与设计】P1908 逆序对,P1637 三元上升子序列,树状数组区间和应用
P1908 逆序对
逆序对
题目描述
猫猫 TOM 和小老鼠 JERRY 最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。
最近,TOM 老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中 a i > a j a_i>a_j ai>aj
且 i < j i<j i<j 的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。注意序列中可能有重复数字。Update:数据已加强。
输入格式
第一行,一个数 n n n,表示序列中有 n n n个数。
第二行 n n n 个数,表示给定的序列。序列中每个数字不超过 1 0 9 10^9 109。
输出格式
输出序列中逆序对的数目。
样例 #1
样例输入 #1
6 5 4 2 6 3 1
样例输出 #1
11
提示
对于 25 % 25\% 25% 的数据, n ≤ 2500 n \leq 2500 n≤2500
对于 50 % 50\% 50% 的数据, n ≤ 4 × 1 0 4 n \leq 4 \times 10^4 n≤4×104。
对于所有数据, n ≤ 5 × 1 0 5 n \leq 5 \times 10^5 n≤5×105
请使用较快的输入输出
应该不会 O ( n 2 ) O(n^2) O(n2) 过 50 万吧 by chen_zhe
求解逆序对的个数,按照每一个下标对应元素,以这个元素为二元组前者所拥有的逆序对的个数.
二元组意思是下标{i,j}组合,并且满足i<j.这样作为一个二元组.arr数组中有1~n下标的元素,遍历所有位置的元素,考虑i位置元素作为二元组中,下标较小的一个,看这样的元素构成的逆序对有多少个.
分别考虑0下标作为二元组较小下标,这样的所有二元组中的逆序对的个数.再考虑1下标作为二元组较小下标,这样的所有二元组中的逆序对的个数,依次类推,
很容易发现这样的详略可以不重不漏遍历所有的情况.
考虑i位置元素作为二元组较小下标,此时要求逆序对的个数,我们需要直到下标i+1~n区间中所有元素值小于i位置元素值的个数,个数就是逆序对的个数.
构建元素值映射个数的结构,只需要遍历<=i-1的前缀和即可.
很容易发现元素值映射个数结构,元素值可能是负数,并且不需要12345678连续的不少的元素值映射个数.
如果arr数组分别是145563,我们发现2元素值一直都没出现,所以2映射数量是可以不需要的.
因此需要做离散化操作.
离散化操作,元素值按照从小到大排序并且去重,元素值映射下标,下标从1开始,依次对应.
只需要利用map结构,将所有的元素值加入map中,然后遍历map依次赋值second为1,2,3,…以此类推.
这样我们只需要构建index映射数量的结构,index一定是正数,并且是连续的.
从后往前遍历i位置元素,查询逆序对个数,arr[i]映射index,1~index-1的前缀和,得到的就是逆序对的个数.
更新index位置的个数.以此类推.
动态维护单点更新和区间和操作,利用树状数组.
#include<bits/stdc++.h>
using namespace std;#define int long long
#define endl '\n'int n; // 定义一个全局变量 n,表示序列中的数目
vector<int> arr; // 定义一个全局向量 arr,用来存储输入的序列
int ret; // 定义一个全局变量 ret,用来存储逆序对的数量
map<int, int> arr_index; // 定义一个全局 map,用来存储序列中每个数字的索引// 树状数组类定义
class Tree {
public:vector<int> tree; // 定义一个向量 tree,用来存储树状数组// 计算 lowbitint lowbit(int i) {return i & -i; // 返回 i 和 -i 的按位与,获取最低位的 1}// 在树状数组中增加值void add(int i, int k) {while (i <= n) { // 从索引 i 开始,向上更新树状数组tree[i] += k; // 增加 ki += lowbit(i); // 移动到下一个需要更新的位置}}// 计算前缀和int sum(int i) {int ret = 0; // 初始化结果为 0while (i > 0) { // 从索引 i 开始,向下计算前缀和ret += tree[i]; // 加上当前索引的值i -= lowbit(i); // 移动到下一个需要计算的位置}return ret; // 返回前缀和}// 计算区间和int range(int l, int r) {return sum(r) - sum(l - 1); // 返回区间 [l, r] 的和}// 默认构造函数Tree() {}// 使用给定数组构造树状数组Tree(vector<int> arr) {tree.assign(arr.size(), 0); // 初始化树状数组for (int i = 1; i <= arr.size(); i++) {add(i, arr[i]); // 将数组中的值添加到树状数组中}}
};Tree t1; // 定义一个全局的树状数组对象// 主解题函数
void solve() {ret = 0; // 初始化逆序对数量为 0t1.tree.assign(n + 5, 0); // 初始化树状数组的大小int index = 1; // 初始化索引为 1for (auto& xx : arr_index) {xx.second = index++; // 给每个数字分配一个唯一的索引}for (int i = n; i >= 1; i--) {int index = arr_index[arr[i]]; // 获取当前数字的索引ret += t1.sum(index - 1); // 计算比当前数字小的数字的数量t1.add(index, 1); // 在树状数组中增加当前数字}cout << ret << endl; // 输出逆序对数量
}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 快速输入输出cin >> n; // 读取序列的长度arr.assign(n + 5, 0); // 初始化序列数组for (int i = 1; i <= n; i++) {cin >> arr[i]; // 读取序列中的每个数字arr_index[arr[i]]; // 在 map 中记录每个数字}solve(); // 调用解题函数
}
P1637 三元上升子序列
三元上升子序列
题目描述
Erwin 最近对一种叫
thair
的东西巨感兴趣。。。在含有 n n n 个整数的序列 a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a1,a2,…,an 中,三个数被称作
thair
当且仅当 i < j < k i<j<k i<j<k 且
a i < a j < a k a_i<a_j<a_k ai<aj<ak。求一个序列中
thair
的个数。输入格式
开始一行一个正整数 n n n,
以后一行 n n n 个整数 a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a1,a2,…,an。
输出格式
一行一个整数表示
thair
的个数。样例 #1
样例输入 #1
4 2 1 3 4
样例输出 #1
2
样例 #2
样例输入 #2
5 1 2 2 3 4
样例输出 #2
7
提示
样例2 解释
7 7 7 个
thair
分别是:
- 1 2 3
- 1 2 4
- 1 2 3
- 1 2 4
- 1 3 4
- 2 3 4
- 2 3 4
数据规模与约定
- 对于 30 % 30\% 30% 的数据 保证 n ≤ 100 n\le100 n≤100;
- 对于 60 % 60\% 60% 的数据 保证 n ≤ 2000 n\le2000 n≤2000;
- 对于 100 % 100\% 100% 的数据 保证 1 ≤ n ≤ 3 × 1 0 4 1 \leq n\le3\times10^4 1≤n≤3×104, 1 ≤ a i ≤ 1 0 5 1\le a_i\leq 10^5 1≤ai≤105。
递增三元组,遍历每一个位置元素i,i作为三元组最右侧的k下标,最大的下标,此时拥有的递增三元组的个数.
等价于求1~i-1位置小于我当前位置元素值的递增二元组的个数.
如果一个数组存储1~i-1映射二元组个数,只需要i求前缀和.
维护二元组数组,遍历每一个位置元素i,作为二元组较大的下标,此时拥有的二元组的个数是1~i-1中有多少个比我小的元素个数.
利用上一道题的思路可以利用数组数组求1~i-1中有多少比我小的元素个数.
#include<bits/stdc++.h>
using namespace std;#define int long long // 定义 int 为 long long 类型,方便处理大数
#define endl '\n' // 定义换行符为 endl,方便输出int n; // 定义全局变量 n,表示序列中的数目
vector<int> arr; // 定义全局向量 arr,用于存储输入的序列
int ret; // 定义全局变量 ret,用于存储三元上升子序列的数量
map<int, int> arr_index; // 定义全局 map,用于存储序列中每个数字的索引// 树状数组类定义
class Tree {
public:vector<int> tree; // 定义一个向量 tree,用于存储树状数组// 计算 lowbitint lowbit(int i) {return i & -i; // 返回 i 和 -i 的按位与,获取最低位的 1}// 在树状数组中增加值void add(int i, int k) {while (i <= n) { // 从索引 i 开始,向上更新树状数组tree[i] += k; // 增加 ki += lowbit(i); // 移动到下一个需要更新的位置}}// 计算前缀和int sum(int i) {int ret = 0; // 初始化结果为 0while (i > 0) { // 从索引 i 开始,向下计算前缀和ret += tree[i]; // 加上当前索引的值i -= lowbit(i); // 移动到下一个需要计算的位置}return ret; // 返回前缀和}// 计算区间和int range(int l, int r) {return sum(r) - sum(l - 1); // 返回区间 [l, r] 的和}// 默认构造函数Tree() {}// 使用给定数组构造树状数组Tree(vector<int> arr) {tree.assign(arr.size(), 0); // 初始化树状数组for (int i = 1; i <= arr.size(); i++) {add(i, arr[i]); // 将数组中的值添加到树状数组中}}
};Tree t1, t2; // 定义两个全局的树状数组对象// 主解题函数
void solve() {t1.tree.assign(n + 5, 0); // 初始化第一个树状数组的大小t2.tree.assign(n + 5, 0); // 初始化第二个树状数组的大小int index = 1; // 初始化索引为 1for (auto& xx : arr_index) {xx.second = index++; // 给每个数字分配一个唯一的索引}ret = 0; // 初始化三元上升子序列的数量为 0for (int i = 1; i <= n; i++) {int index = arr_index[arr[i]]; // 获取当前数字的索引t1.add(index, 1); // 在第一个树状数组中增加当前数字t2.add(index, t1.sum(index - 1)); // 在第二个树状数组中增加当前数字左侧比它小的数字的数量ret += t2.sum(index - 1); // 累加比当前数字小的数字的数量,得到三元上升子序列的数量}cout << ret << endl; // 输出三元上升子序列的数量
}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 快速输入输出cin >> n; // 读取序列的长度arr.assign(n + 5, 0); // 初始化序列数组for (int i = 1; i <= n; i++) {cin >> arr[i]; // 读取序列中的每个数字arr_index[arr[i]]; // 在 map 中记录每个数字}solve(); // 调用解题函数
}
结尾
最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。
同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。
谢谢您的支持,期待与您在下一篇文章中再次相遇!
相关文章:
【一百零八】【算法分析与设计】P1908 逆序对,P1637 三元上升子序列,树状数组区间和应用
P1908 逆序对 逆序对 题目描述 猫猫 TOM 和小老鼠 JERRY 最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。 最近,TOM 老猫查阅到一个人类称之为“逆序对”的东西,这东西…...
【RK3568】制作Android11开机动画
Android 开机 logo 分为两种:静态显示和动态显示。静态显示就是循环显示一张图片;动态显示就是以特定帧率顺序显示多张图片 1.准备 android logo 图片 Android logo最好是png格式的,因为同一张图片的情况下,png 格式的比 jpg和b…...
chrony内网同步服务器时间
当前需要在10.26.24.62和10.26.24.61两个服务器上设置chrony同步时间,其中10.26.24.62为NTP时间服务器,10.26.24.61去10.26.24.62同步时间 检查Chrony配置文件: 确认10.26.24.62(NTP服务器)的配置文件 /etc/chrony/c…...
SSM物流管理系统的设计与实现-计算机毕业设计源码44323
摘 要 科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流,人类发展的历史正进入一个新时代。在现实运用中,应用软件的工作…...
STM32CubeIDE使用过程记录
最近在做一款机器人的开发,使用到了STM32CubeIDE,这里记录一些使用技巧方便后续查阅。 STM32CubeIDE使用过程记录 快捷键开启代码自动补全功能看门狗设置CRC设置IO口取反定时器设置 及 定时器中断外部中断GPIO配置STC15单片机GPIO模式配置片内闪存&#…...
angular2开发知识点
目录 文章目录 一、API 网关地址 配置二、服务注册使用三、模块组件注册使用四、html中style类动态绑定1. 单个类的绑定:[class.special]"isSpecial"2. 多个类的绑定:[ngClass]"{selected:status ,saveable: this.canSave,}"3. 单个…...
【机器学习】机器学习与智能交通在智慧城市中的融合应用与性能优化新探索
文章目录 引言机器学习与智能交通的基本概念机器学习概述监督学习无监督学习强化学习 智能交通概述交通流量预测交通拥堵管理智能信号控制智能停车管理 机器学习与智能交通的融合应用实时交通数据分析数据预处理特征工程 交通流量预测与优化模型训练模型评估 智能信号控制与优化…...
走的人多了,也便成了路(七)
好多年前就听到这样的说法:一流的企业做标准,二流的企业做品牌,三流的企业做产品。 在通信行业待久了,经历了移动通信技术标准的发展历程,体会到很多事情没有那么神秘,甚至由于一些偶然因素的出现ÿ…...
UE5中在地形中加入湖、河
系统水资产添加 前提步骤123 完成 前提 使用版本 UE5.0.3,使用插件为UE内置的Water和water Extras. 步骤 1 记得重启 2 增加地形,把<启用编辑图层>勾选 如果地形没有勾选上编辑图层,那么就会导致湖、河等水景象无法融入地形。 如果忘记勾选…...
【280个shell脚本】----提示运维工作效率
1.MySQL 数据库备份单循环 #!/bin/bash DATE$(date %F_%H-%M-%S) HOSTlocalhost USERbackup PASS123.com BACKUP_DIR/data/db_backup DB_LIST$(mysql -h$HOST -u$USER -p$PASS -s -e "show databases;" 2>/dev/null |egrep -v "Database|information_schema…...
从零开始搭建Electron项目之运行例程
最好的学习方式就是:给一段能够运行的代码示例。 本文给出了例程资源,以及运行的步骤。 在国内开发electron有一点特别不好,就是如果不爬梯子,下载依赖容易出错。 一、例程资源 到如下路径下载例程到本地。 GitCode - 全球开发者…...
MySQL逻辑备份
目录 一.mysqldump 基本命令: 参数选项: 示例 备份整个数据库 备份多个数据库 备份所有数据库 仅备份数据库结构 仅备份特定表 添加选项以有效处理锁表问题 恢复数据 恢复数据库 恢复库中的表 使用source恢复 注意事项 二. mysqlpu…...
python 获取网页链接图片
python 获取 网页图片 在Python中,可以使用requests库获取网页内容,再使用BeautifulSoup解析网页,提取图片链接,最后保存图片到本地。以下是一个简单的例子: import requests from bs4 import BeautifulSoup import o…...
Leetcode 力扣114. 二叉树展开为链表 (抖音号:708231408)
给你二叉树的根结点 root ,请你将它展开为一个单链表: 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺序相同。 示例 1…...
文刻ai工具跟绘唐AI工具有什么区别
文刻AI工具和绘唐AI工具是两种不同的人工智能工具。点击查看 文刻AI工具是一种自然语言处理工具,可以用于生成、修改和校对文本。它可以帮助用户更高效地写作,提供词汇和语法建议,检查拼写和语法错误,并提供自动补全和自动纠正功…...
手写kNN算法的实现-用欧几里德空间来度量距离
kNN的算法思路:找K个离预测点最近的点,然后让它们进行投票决定预测点的类型。 step 1: kNN存储样本点的特征数据和标签数据step 2: 计算预测点到所有样本点的距离,关于这个距离,我们用欧几里德距离来度量(其实还有很多…...
IGraph使用实例——线性代数计算(blas)
1 概述 在图论中,BLAS(Basic Linear Algebra Subprograms)并不直接应用于图论的计算,而是作为一套线性代数计算中通用的基本运算操作函数集合,用于进行向量和矩阵的基本运算。然而,这些基本运算在图论的相…...
【MySQL】(基础篇五) —— 排序检索数据
排序检索数据 本章将讲授如何使用SELECT语句的ORDER BY子句,根据需要排序检索出的数据。 排序数据 还是使用上一节中的例子,查询employees表中的last_name字段 SELECT last_name FROM employees;输出结果: 发现其输出并没有特定的顺序。其实…...
C++ C_style string overview and basic Input funcitons
write in advance 最近在做题,遇到一个简单的将console的输入输出到文件中的简单题目,没有写出来。悔恨当初没有踏实地总结string 相关的 I/O 以及与文件的操作。这篇文章旨在记录基础的字符I/O, 简单常用的文件I/O操作函数。 当然,你会说C…...
VS2022+Qt雕刻机单片机马达串口上位机控制系统
程序示例精选 VS2022Qt雕刻机单片机马达串口上位机控制系统 如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助! 前言 这篇博客针对《VS2022Qt雕刻机单片机马达串口上位机控制系统》编写代码,代码整洁&a…...
Android Ble低功耗蓝牙开发
一、新建项目 在Android Studio中新建一个项目,如下图所示: 选择No Activity,然后点击Next 点击Finish,完成项目创建。 1、配置build.gradle 在android{}闭包中添加viewBinding,用于获取控件 buildFeatures {viewB…...
Visual Studio的快捷按键
Visual Studio的快捷按键对于提高编程效率至关重要。以下是一些常用的Visual Studio快捷按键,并按照功能进行分类和归纳: 1. 文件操作 Ctrl O:打开文件Ctrl S:保存文件Ctrl Shift S:全部保存Ctrl N:…...
【WEB系列】过滤器Filter
Filter,过滤器,属于Servlet规范,并不是Spring独有的。其作用从命名上也可以看出一二,拦截一个请求,做一些业务逻辑操作,然后可以决定请求是否可以继续往下分发,落到其他的Filter或者对应的Servl…...
[书生·浦语大模型实战营]——LMDeploy 量化部署 LLM 实践
1.基础作业 1.1配置 LMDeploy 运行环境 创建开发机 创建新的开发机,选择镜像Cuda12.2-conda;选择10% A100*1GPU;点击“立即创建”。注意请不要选择Cuda11.7-conda的镜像,新版本的lmdeploy会出现兼容性问题。其他和之前一样&…...
TiDB-从0到1-配置篇
TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇TiDB-从0到1-配置篇 一、系统配置 TiDB的配置分为系统配置和集群配置两种。 其中系统配置对应TiDB Server(不包含TiKV和PD的参数࿰…...
微信小程序按钮设计与交互:打造极致用户体验
微信小程序作为一种流行的应用形式,其界面设计和交互体验对于用户吸引力和留存率至关重要。其中,按钮作为用户与小程序进行交互的主要方式之一,其设计和实现直接影响到用户体验的质量。在本文中,我们将探讨微信小程序按钮的设计与…...
ES6中如何使用class和extends关键字实现继承?
在ES6中,可以使用class关键字来定义类,使用extends关键字来实现继承。下面是一个示例: // 父类 class Parent {constructor(name) {this.name name;}sayHello() {console.log(Hello, my name is ${this.name});} }// 子类 class Child ex…...
Linux:基本指令
文章目录 ls指令pwd指令cd指令touch指令mkdir指令rmdir指令 && rm指令cp指令man指令echo指令输出重定向追加重定向 cat指令输入重定向 mv指令which指令alias指令more && less指令head && tail指令事件相关的指令date显示时间戳 cal指令find指令grep指令…...
商业C++静态代码检测工具PC-lint Plus 、 polysace和sonarqube对比
商业C静态代码检测工具PC-lint Plus 、 polysace和sonarqube对比 特性/工具PC-lint PlusPolyspaceSonarQube主要功能高精度静态代码分析、编码标准检查高级静态分析和形式验证、优化嵌入式系统综合性代码质量管理、静态分析、技术债务管理集成方式可集成到IDE和构建系统与开发…...
邬家桥公园
文|随意的风 原文地址 我游览过现存规模最大、保存最完整的皇家园林颐和园,瞻仰过拥有世界上最大祭天建筑群的天坛公园,那都是多年前的事情了。 邬家桥公园相比颐和园、天坛公园,气势雄伟倒谈不上。它没有西湖的水平如镜ÿ…...
网上接单干活的平台/北京度seo排名
领域驱动模型设计与微服务架构落地-从项目去剖析领域驱动领域驱动模型设计与微服务架构落地-从项目去剖析领域驱动事件风暴(Event Storiming)事件风暴目的什么是事件风暴事件风暴的优点事件风暴应用场景事件风暴准备场地设置海报纸邀请正确的人来参与事件…...
长沙网站优化方法/网站的网站建设
以下代码环境要求:win8或win10, .net4.5IIS8 win7上是IIS7,win7上.net本身不直接支持websocket, win7可以用superwebsocket, 或自己根据协议用TCPListener实现 handler代码: using System; using System.Net.WebSockets; using System.Text;…...
网站没有icp备案是不是就是骗子/品牌推广的三个阶段
前言众所周知,每年的三月份和四月份都是招聘、找工作的高峰期,所以被人们成为金三银四,所以小编特地整理了一些关于Python的面试题,希望对你们有所帮助!(一)、这两个参数是什么意思:*args,**kwa…...
wordpress文章摘要插件/营销推广活动方案
背景需求 随着雪亮工程、明厨亮灶、手机看店、智慧幼儿园监控等行业开始将传统的安防摄像头进行互联网、微信直播,我们知道摄像头直播的春天了。将安防摄像头或NVR上的视频流转成互联网直播常用的RTSP、RTMP、HTTP-FLV、HLS等流格式再分发给用户端进行直播…...
python采集到wordpress/目录搜索引擎有哪些
简单的爬虫架构 调度器 URL管理器 管理待抓取的URL集合和已抓取的URL,防止重复抓取,防止死循环 功能列表 1:判断新添加URL是否在容器中 2:向管理器添加新URL 3:判断容器是否为空 4:将已爬取URL移动到已爬取…...
如何自己制作网站/学生个人网页制作
需要一个可以选择部门的功能,开始选用的是easyUI tree,不过最后被嫌弃了,只好寻找更优的解决方法,当然也可以通过异步加载的方式来避免一次性载入速度慢的问题,但这不在考虑范围内。 终于在《打造基于jQuery的高性能Tr…...