当前位置: 首页 > news >正文

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;
}

相关文章:

  • 《合成孔径雷达成像算法与实现》Figure6.8
  • 零基础学Python之整合MySQL
  • Flask 入门7:使用 Flask-Moment 本地化日期和时间
  • macOS的设置与常用软件(含IntelliJ IDEA 2023.3.2 Ultimate安装,SIP的关闭与开启)
  • 系统架构设计师-22年-上午答案
  • 《Git 简易速速上手小册》第1章:Git 基础(2024 最新版)
  • 微信小程序解决华为手机保存图片到相册失败
  • 5.electron之主进程起一个本地服务
  • 打卡今天学习的命令 (linux
  • Swift Combine 管道 从入门到精通三
  • Java实现批量视频抽帧2.0
  • java list集合相关介绍和方法使用操作
  • Quicker读取浏览器的书签(包括firefox火狐)
  • Camunda流程引擎数据库架构
  • Redis面试题43
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • 【译】理解JavaScript:new 关键字
  • 2017-09-12 前端日报
  • android图片蒙层
  • DataBase in Android
  • express如何解决request entity too large问题
  • JavaScript创建对象的四种方式
  • Joomla 2.x, 3.x useful code cheatsheet
  • Mybatis初体验
  • Object.assign方法不能实现深复制
  • oschina
  • Vue2 SSR 的优化之旅
  • Vue全家桶实现一个Web App
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 动态规划入门(以爬楼梯为例)
  • 那些被忽略的 JavaScript 数组方法细节
  • 如何胜任知名企业的商业数据分析师?
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 实现简单的正则表达式引擎
  • 首页查询功能的一次实现过程
  • 微信小程序--------语音识别(前端自己也能玩)
  • 我的zsh配置, 2019最新方案
  • 用 Swift 编写面向协议的视图
  • 数据可视化之下发图实践
  • ​MySQL主从复制一致性检测
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #传输# #传输数据判断#
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (7)STL算法之交换赋值
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (MATLAB)第五章-矩阵运算
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (算法)N皇后问题
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复