1236. 递增三元组:做题笔记

目录

暴力

代码

二分

代码

前缀和 

代码

推荐视频讲解


暴力

这道题说的是有三个元素数量相同的数组,想知道有多少个三元组满足:三个数分别来自 A B C数组且呈现递增。

我想的是既然要求递增,那就先把数组数据都排一下序,直接sort函数用起来。因为排了序的话就说明在某个数之后的所有数都是满足条件的,直接进行累加就可以。

第一个数A数组肯定要先遍历一下的(是的我当时做的时候压根没想到其他的),我就想着我们既然想利用排完序的好处,那就从这想。

在第一层循环的基础上,在对第二层数据挑选的时候,就可以利用二分找到我们上面所说的“某个数”,这里的某个数其实也就是当前B数组里第一个大于当前外层循环正在处理的A数组的这个元素,我们知道在这个数之后的B数组中的数都是一种选择的可能。同理,到了最内层对从C数组中选的第三个数的可能性也就是在前两个数确定的这种情况下满足条件的可能性。

这样就枚举了所有可能性,肯定超时的。且这样的写法一个数据都过不了呜呜😭

我就没想到到底怎么优化掉第二层循环,,

代码

#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int N=1e5+10;
int a[N],b[N],c[N],b1[N],c1[N];
int n;
int find(int q[],int x)
{
	int l=0,r=n;
	while(l<r)
	{
		int mid=(l+r)/2;
		if(q[mid]>x)r=mid-1;
		else l=mid;
	}
	if(q[l]>x)return l;
	else if(q[l]==x)return l+1;
	else return -1;
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	cin>>n;
	for(int i=0;i<n;i++)cin>>a[i];
	for(int i=0;i<n;i++)cin>>b[i];
	for(int i=0;i<n;i++)cin>>c[i];
	
	sort(a, a+n);
	sort(b, b+n);
	sort(c, c+n);
	
	int cnt=0;
	for(int i=0;i<n;i++)
	{
		
		for(int j=find(b,a[i]);j<n;j++)
		{
			//第三层循环还是好优化的(不过没什么卵用,因为双层循环仍然tle😜)
			/*
			for(int k=find(c,b[j]);k<n && k!=-1;k++)
			{
				cnt++;
			}*/

			int k=find(c,b[j]);
			cnt+=n-k;
		}
	}
	cout<<cnt;
	return 0;
 } 

二分

就是看了讲解才知道我们想降成一层循环,那留下来的这层循环就必须是中间的B数组。

因为A B C 三元组想递增嘛,那 A<B,C>B。遍历B数组每个元素,可以通过二分找到A数组中第一个大于当前B数组中元素的数的位置,和C数组中第一个大于当前B数组中元素的数的位置,通过元素总数与该位置的相减,得到其中间的元素个数。

我们可以写二分模板,也可以使用 lower_bound和upper_bound 函数,感觉直接用函数很方便。就像那个sort函数一样。

由于这两个函数的操作对象应该是有序的,我们需要对数组进行排序。

补充一下这两个函数的用法:

lower_bound(begin, end, value):在从小到大排好序的数组中,在数组的 [begin, end) 区间中二分查找第一个大于或等于value的数,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标


upper_bound(begin, end, value):在从小到大排好序的数组中,在数组的 [begin, end) 区间中二分查找第一个大于value的数,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。


这两个函数的时间复杂度都是O(logN),其中N是搜索空间中的元素数量。 

代码

#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int N=1e5+10;
int a[N],b[N],c[N];
int n;
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	cin>>n;
	for(int i=0;i<n;i++)cin>>a[i];
	for(int i=0;i<n;i++)cin>>b[i];
	for(int i=0;i<n;i++)cin>>c[i];
	
	sort(a, a+n);
	sort(b, b+n);
	sort(c, c+n);
	
	int cnt=0;
	for(int i=0;i<n;i++)
	{
		int l=lower_bound(a,a+n,b[i])-a,r=n-(upper_bound(c,c+n,b[i])-c);
		cnt+=l*r;
	}
	cout<<cnt;
	return 0;
 }

l 是数组 a 中小于 b[i] 的元素的数量,r 是数组 c 中大于 b[i] 的元素的数量。

前缀和 

这里前缀和的思路也是以B数组的遍历为主。

记录下所有数字出现的次数,预处理出前缀和,对A C数组进行排序,与B数组当前处理的元素进行比较,通过前缀和的运算得到A数组小于当前元素的个数,和C数组大于当前元素的个数,将这两个数相乘,并随着B数组的遍历对每一种情况进行累加得到最终结果。

关于前缀和的运算:A数组想得到小于当前元素的个数,直接b[i]-1的前缀和得到的就是想要的区间的前缀和  ( sa[b[i]-1] )

C数组想得到大于当前元素的个数,用 N 处的前缀和减去b[i]当前元素的前缀和即可( sc[N]-sc[b[i]] )

需要注意的是,由于数组中每个元素的数据范围是0-1e5,因此在前缀和计算中要从0开始,循环1e5次,关于数组越界问题:

代码

#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int N=1e5+10;
int a[N],b[N],c[N];
int a1[N],c1[N];//存放每个数出现次数
int sa[N],sc[N];//计算a1,c1的前缀和
int as[N],cs[N];//通过前缀和的运算处理出所有可能的情况
//as代表比b[i]小的数的个数  cs代表比b[i]大的数的个数
int n;
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	cin>>n;
	for(int i=0;i<n;i++)cin>>a[i];
	for(int i=0;i<n;i++)cin>>b[i];
	for(int i=0;i<n;i++)cin>>c[i];
	
	for(int i=0;i<n;i++)a1[a[i]]++;
	for(int i=0;i<=N;i++)sa[i]=sa[i-1]+a1[i];
	for(int i=0;i<n;i++)as[i]=sa[b[i]-1];
	
	for(int i=0;i<n;i++)c1[c[i]]++;
	for(int i=0;i<=N;i++)sc[i]=sc[i-1]+c1[i];
	for(int i=0;i<n;i++)cs[i]=sc[N]-sc[b[i]];
	
	int cnt=0;
	for(int i=0;i<n;i++)
	{
		cnt+=as[i]*cs[i];
	}
	cout<<cnt;
	return 0;
 }

推荐视频讲解

【蓝桥杯真题,递增三元组,前缀和问题】

老师讲的很清晰。推荐观看

AcWing 1236. 递增三元组(三种算法+胎教注释)​​​​​​​

这个题解不知道大家能看到不能。


感觉思路理解还行,但是就是明白了思路到写对题之间还有很长距离,好多细节问题emm. 

哎好难🥀🥀🥀🥀

有问题欢迎指出,一起加油!!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

行车记录打不开?别慌,数据恢复有高招!

行车记录打不开&#xff0c;这恐怕是许多车主都曾经遭遇过的烦恼。在驾驶途中&#xff0c;行车记录仪本应是记录美好瞬间、保障行车安全的重要工具&#xff0c;但一旦它出现打不开的情况&#xff0c;所有的期待与信赖便瞬间化为乌有。面对这种情况&#xff0c;我们该如何应对&a…

HQL,SQL刷题,尚硅谷(初级)

目录 相关表数据&#xff1a; 题目及思路解析&#xff1a; 多表连接 1、课程编号为"01"且课程分数小于60&#xff0c;按分数降序排列的学生信息 2、查询所有课程成绩在70分以上 的学生的姓名、课程名称和分数&#xff0c;按分数升序排列 3、查询该学生不同课程的成绩…

python_绘图_多条折线图绘制_显示与隐藏

1. 需求 给定一个二维数组 100行, 5列, 每一列绘制一条折线, 横轴为行索引, 纵轴为对应位置的值, 绘制在一个子图里面, 使用python plot, 使用随机颜色进行区别添加显示和隐藏按钮, 可以对每条折线进行显示和隐藏 2. 代码 import numpy as np import matplotlib.pyplot as p…

软件心学格物致知篇(5)愿望清单上篇

愿望清单 前言 最近发现愿望清单是一个很有意思的词&#xff0c;结合自己的一些过往经验得到一点点启发。 我发现在众多领域都有东西想伪装成它。 比如一些企业的企业战略&#xff0c;比如客户提出的一些软件需求&#xff0c;比如一些系统的架构设计指标&#xff0c;比如一…

C语言动态内存讲解+通讯录2.0

文章目录 前文malloc和freecallocrealloc枚举常量的简单说明及使用 通讯录2.0动态开辟通讯录,满了就扩容保存数据和载入数据 通讯录2.0演示推荐好用的软件 前文 本文主要介绍动态开辟的几个函数,以及改进之前的通讯录。 我们局部变量等是在栈区上开辟空间的,而我们动态开辟的空…

Learning Discriminative Representations for Skeleton Based Action Recognition

标题&#xff1a;基于骨架的动作识别的学习判别性表示 原文链接&#xff1a;Learning Discriminative Representations for Skeleton Based Action Recognition (thecvf.com) 源码链接&#xff1a;https://github.com/zhysora/FR-Head 发表&#xff1a;CVPR 摘要 最近&…

【论文复现|智能算法改进】动态透镜成像学习人工兔优化算法及应用

目录 1.算法原理2.改进点3.结果展示4.参考文献 1.算法原理 【智能算法】人工兔优化算法&#xff08;ARO&#xff09;原理及实现 2.改进点 非线性递减能量因子&#xff1a; A ( t ) ( A max ⁡ − A min ⁡ ) ( 1 − sin ⁡ ( ( t T ) n π 2 ) (1) \begin{aligned}A\left…

李宏毅深度强化学习导论——当奖励是稀疏的

引言 这是李宏毅强化学习的笔记&#xff0c;主要介绍如何处理稀疏奖励问题。 稀疏奖励 当我们拿Actor和环境互动后可以得到很多奖励&#xff0c;整理之后可以得到分数 A A A&#xff0c;然后可以训练Actor。 但RL中有时会出现多数情况下奖励为零&#xff0c;此时我们不知道动…

Verilog基础【二】

3.1 Verilog 连续赋值 关键词&#xff1a;assign&#xff0c; 全加器 连续赋值语句是 Verilog 数据流建模的基本语句&#xff0c;用于对 wire 型变量进行赋值。&#xff1a; assign LHS_target RHS_expression &#xff1b;LHS&#xff08;left hand side&#xff09;…

卷积层+多个输入通道

卷积层多输入输出通道 在深度学习中&#xff0c;卷积神经网络&#xff08;CNN&#xff09;通常用于处理具有多个输入通道的数据。当输入数据具有多个通道&#xff08;例如彩色图像的RGB通道&#xff09;时&#xff0c;卷积操作可以同时在每个通道上进行&#xff0c;并将各通道的…

软件测试-进阶篇

目录 测试的分类1 按测试对象划分1.1 界面测试1.2 可靠性测试1.3 容错性测试1.4 文档测试1.5 兼容性测试1.6 易用性测试1.7 安装卸载测试1.8 安装测试1.9 性能测试1.10 内存泄漏测试 2 按是否查看代码划分2.1 黑盒测试&#xff08;Black-box Testing&#xff09;2.2 白盒测试&a…

新闻管理系统(源码+文档)

新闻管理系统&#xff08;小程序、ios、安卓都可部署&#xff09; 文件包含内容程序简要说明含有功能项目截图客户端新闻详情新闻首页分类退出登录个人中心拨打客服热线注册界面个人资料新闻评论成功 管理端用户管理分类管理新闻管理 文件包含内容 1、搭建视频 2、流程图 3、开…

windows下部署llama.cpp

下载cmake 下载地址 解压&#xff0c;设置Path环境变量D:\CMake\bin 打开cmd输入cmake -version 安装mingw powershell下执行 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser iex "& {$(irm get.scoop.sh)} -RunAsAdmin" scoop bucket add extras s…

Android获取本地文件目录

一、实现效果 一个简单的demo。点击按钮&#xff0c;获取本地文件目录&#xff0c;可以选择图片&#xff0c;展示选取的对应图片和展示存储路径。如图所示&#xff1a; 二、实现方式 1. 权限 AndroidManifest.xml文件里面添加权限 <uses-permission android:name"a…

【御控物联】JavaScript JSON结构转换(12):对象To数组——键值互换属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、核心构件之转换映射三、案例之《JSON对象 To JSON数组》四、代码实现五、在线转换工具六、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换…

牛客2024年愚人节比赛(A-K)

比赛链接 毕竟是娱乐场&#xff0c;放平心态打吧。。。 只有A一个考了数学期望&#xff0c;其他的基本都是acmer特有的脑筋急转弯&#xff0c;看个乐呵即可。 A 我是欧皇&#xff0c;赚到盆满钵满&#xff01; 思路&#xff1a; 我们有 p 1 p_1 p1​ 的概率直接拿到一件实…

Oracle Solaris 11.3开工失败问题处理记录

1、故障现像 起初是我这有套RAC有点问题&#xff0c;我想重启1个节点&#xff0c;结果发现重启后该节点的IP能PING通&#xff0c;但SSH连不上去&#xff0c;对应的RAC服务也没有自动启动。 操作系统是solaris 11.3。由于该IP对应的主机是LDOM&#xff0c;于是我去主域上telnet…

html基础:颜色的 5 种表示方法(最全!)

你好&#xff0c;我是云桃桃。一个希望帮助更多朋友快速入门 WEB 前端的程序媛&#xff0c;大专生&#xff0c;2年时间从1800到月入过万&#xff0c;工作5年买房。 分享成长心得。 HTML 颜色在网页设计中扮演着重要角色&#xff0c;给网页增加颜色可以增强用户体验&#xff0c;…

MySQL看这一篇就够了

目录 MySQL安装&#xff08;Linux&#xff09; 1、仓库安装 2、本地安装 3、容器安装 MySQL体系结构 连接层 SQL层 存储引擎层 MySQL存储引擎的介绍 常用存储引擎的特性比对 InnoDB的逻辑存储结构 系统文件层 MySQL库表操作 库操作 表操作 创建表 查看表 删除…

snmp服务

双击 安装snmputil和MIB Browser getSwitchStatus.cpp&#xff1a; #include <iostream> #include <stdio.h> #include <net-snmp/net-snmp-config.h> #include <net-snmp/net-snmp-includes.h>using namespace std;int main() {init_snmp("getS…