2 月 7 日算法练习- 数据结构-树状数组上二分

问题引入

给出三种操作,
0在容器中插入一个数。
1在容器中删除一个数。
2求出容器中大于a的第k大元素。

树状数组的特点就是对点更新,成段求和,而且常数非常小。原始的树状数组只有两种操作,在某点插入一个数和求1到i的所有数的和。

这道题目一共有三种操作,但是实质上其实只有两种:插入和询问。插入操作和删除操作可以视为一种,只不过一个是将标记+1,另一个是-1,而插入的数对应于树状数组的下标,这样就可以在log(n)的时间内完成插入和删除。
求大于a的k大元素,可以通过二分枚举答案来完成,枚举的是当前答案在树状数组中的位置,设为m,然后对v[a+1]- v[m]求和就是小
于等于m的数的个数,这一步可以用树状数组的求和操作来完成,然后根据和k的比较来调整m的位置。询问的复杂度也是log(n)的。

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int maxn = 110000;
int tree[maxn];
int q;int lowbit(int x){return x&-x;
}void add(int pos,int x){while(pos<maxn){tree[pos] += x;pos += lowbit(pos);}return;
}
int query(int pos){int res = 0;while(pos){res+=tree[pos];pos -= lowbit(pos);}return res;
}int find(int a,int k){int l = a+1,r = maxn-1;int ans = -1;while(l<=r){int mid = (l+r)>>1;if(query(mid)-query(a)==k)ans = mid;if(query(mid)-query(a)>=k)r = mid-1;else l = mid +1;}return ans;
}int main( ){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);cin>>q;while(q--){int x,y,z;cin>>x;if(x==0){cin>>y;add(y,1);}else if(x==1){cin>>y;if((query(y)-query(y-1))==0)continue;add(y,-1);}else{cin>>y>>z;cout<<find(y,z)<<'\n';}}return 0;
}

算法分析

树状数组+二分复杂度可以比较直接的得到为 nlog2n

修改数组

在这里插入图片描述
思路:利用树状数组+二分。利用树状数组来快速求得区间和从而利用二分来找到第一个大于 i 的数的位置。

#include<iostream>
using namespace std;
const int maxn = 1e5+9;
int a[maxn],vis[maxn],tree[maxn];
int n;int lowbit(int x){return x&-x;
}void add(int k,int x){while(k<maxn){tree[k]+=x;k += lowbit(k);}
}int query(int k){int ans = 0;while(k){ans+=tree[k];k-=lowbit(k);}return ans;
}int main( ){cin>>n;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++){if(!vis[a[i]])vis[a[i]]=1,add(a[i],1);else{int l=a[i],r =maxn,ans = -1;while(l<=r){int mid = (l+r)>>1;if(query(mid)-query(a[i]-1)<mid-a[i]+1)r = mid-1,ans = mid;else l = mid+1;}a[i] = ans;vis[ans]=1;add(ans,1);}}for(int i=1;i<=n;i++)cout<<a[i]<<" \n"[i==n];return 1;
}

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

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

相关文章

Spring Boot3整合Redis

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 前置条件 1.导依赖 2.配置连接信息以及连接池参数 3.配置序列化方式 4.编写测试 前置条件 已经初始化好一个spr…

Spark安装(Yarn模式)

一、解压 链接&#xff1a;https://pan.baidu.com/s/1O8u1SEuLOQv2Yietea_Uxg 提取码&#xff1a;mb4h tar -zxvf /opt/software/spark-3.0.3-bin-hadoop3.2.tgz -C /opt/module/spark-yarn mv spark-3.0.3-bin-hadoop3.2/ spark-yarn 二、配置环境变量 vim /etc/profile…

使用 Kubernetes,基础设施层面如何优化?分享一些解决方案

重点内容 搭配 SmartX 自主研发的 Kubernetes 服务、分布式存储、Kubernetes 原生存储等产品&#xff0c;用户既可基于 SmartX 超融合构筑全栈 Kubernetes 基础设施&#xff0c;也可选择为部署在裸金属、其他虚拟化平台或混合环境的 Kubernetes 集群提供持久化存储支持。 文末…

Linux介绍和命令使用

目录 目录 一、Linux简介 1.1 主流操作系统 1.2 Linux 发展历史 1.3 Linux系统版本 二、Linux安装 三、Linux 目录结构 四、Linux常用命令 4.1 基础常用命令说明 4.2 Linux 命令使用技巧 4.3 Linux 命令格式 4.4 进阶重点常用命令 4.4.1 拷贝移动命令 4.4.2 打包…

3D力导向树插件-3d-force-graph学习002

一、实现效果&#xff1a;节点文字同时展示 节点显示不同颜色节点盒label文字并存节点上添加点击事件 二、利用插件&#xff1a;CSS2DRenderer 提示&#xff1a;以下引入文件均可在安装完3d-force-graph的安装包里找到 三、关键代码 提示&#xff1a;模拟数据可按如下格式填…

Open CASCADE学习|求圆的切线与切点

在几何学中&#xff0c;一个圆的切线被定义为与圆相切于一点的直线&#xff0c;而该点被称为切点。这意味着切线在切点处与圆仅有一个交点&#xff0c;并且在该点处&#xff0c;切线的方向与圆的半径垂直。 以下是关于圆的切线和切点的一些重要性质&#xff1a; 切线与半径的…

用于电机控制应用的动态制动电阻器了解下

大型直流和交流电机驱动器通常提供用于安装制动电阻器的端子。这些电阻器是什么&#xff0c;它们如何减慢机器的速度&#xff1f;必须考虑哪些危险和注意事项&#xff1f; 机械能 任何运动中的机器都具有动能。这种能量是一些储存的势能被“倾倒”到电机或执行器中的结果&…

ArcGIS学习(六)地理数据库

ArcGIS学习(六)地理数据库 上个任务我们讲了一个非常重要的知识点一一坐标系。这个任务我们带来另外一个很重要的知识点一一地理数据库。 地理数据库的内容相比于坐标系简单很多! 首先,先让我们来学习下地理数据库的理论。 ArcGIS 中的地理数据库(Geodatabase)是一个用…

FPGA_vga显示

一 VGA 1.1 VGA VGA是视频图像阵列&#xff0c;是一种使用模拟信号进行视频传输的标准协议。 1.2 VGA接引脚定义 VGA分公母两种&#xff0c;RGB显示标准。 1.3 VGA显示器 VGA显示器采用图像扫描的方式进行图像显示&#xff0c;将构成图像的像素点&#xff0c;在行同步信号…

Android中的MVVM

演变 开发常用的框架包括MVC、MVP和本文的MVVM&#xff0c;三种框架都是为了分离ui界面和处理逻辑而出现的框架模式。mvp、mvvm都由mvc演化而来&#xff0c;他们不属于某种语言的框架&#xff0c;当存在ui页面和逻辑代码时&#xff0c;我们就可以使用这三种模式。 model和vie…

【Linux】vim的基本操作与配置(上)

Hello everybody!今天我们要进入vim的讲解了。学会了vim,咱们就可以在Linux系统上做一些简单的编程啦&#xff01; 那么废话不多说&#xff0c;咱们直接进入正题&#xff01; 1.初识vim vim是一款多模式的文本编辑器&#xff0c;可以对一个文件进行编辑操作。 它一共有三个模…

分享一下 uniapp 打包安卓apk

首先需要安装 Java 环境&#xff0c;这里就不做解释了 第二步&#xff1a;打开 mac 终端 / cmd 命令行工具 使用keytool -genkey命令生成证书 keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore *testalias 是证书别名&am…