IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> NC19427换个角度思考(树状数组离线操作模板题目)+自己对树状数组的理解 -> 正文阅读

[数据结构与算法]NC19427换个角度思考(树状数组离线操作模板题目)+自己对树状数组的理解

链接:https://ac.nowcoder.com/acm/problem/19427
来源:牛客网

题号:NC19427
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
给定一个序列,有多次询问,每次查询区间里小于等于某个数的元素的个数
即对于询问 (l,r,x),你需要输出 \sum_{i=l}^{r}[a_i \le x]∑
i=l
r
?
[a
i
?
≤x] 的值
其中 [exp] 是一个函数,它返回 1 当且仅当 exp 成立,其中 exp 表示某个表达式
输入描述:
第一行两个整数n,m
第二行n个整数表示序列a的元素,序列下标从1开始标号,保证1 ≤ ai ≤ 105
之后有m行,每行三个整数(l,r,k),保证1 ≤ l ≤ r ≤ n,且1 ≤ k ≤ 105
输出描述:
对于每一个询问,输出一个整数表示答案后回车
示例1
输入
复制
5 1
1 2 3 4 5
1 5 3
输出
复制
3
备注:
数据范围
1 ≤ n ≤ 105
1 ≤ m ≤ 105
首先简单讲讲我觉得理解树状数组代码几个比较重要的地方:
在这里插入图片描述

①:树状数组就是一个工具,为了优化修改,查询的工具
细节,看一看具体的实现函数
②:lowbit顾名思义就是求树状数组这个下标的最低二进制位,比方说c【8】,8的二进制表示是1000,所以呢他的lowbit是4,这个lowerbit有啥用处呢,我们直接观察这个树状数组,发现这个本位+lowbit就可以得到覆盖它的最小下标比方说c[8]+自身lowbit就可以得到c[16],减去自身的lowerbit就得到第一个他没有覆盖的区间,c[8]覆盖了8之前的全部区间,因此8-8=0;c[0]==0,所以树状数组还有个注意的地方就是必须预留出0的位置,从1开始。
所以呢,通过lowbit,我们可以得到add操作的刚好覆盖该点的树状数组节点,sum操作中刚好没有被该节点覆盖的点,实现修改与查询的功能。
怎么实现lowbit的功能,就是x&-x,看看计算机负数的存储就知道了。
③:懂了lowbit,add操作就是逐步将他的上一层修改就是了
④:懂了lowbit,sum操作就是查询之前所有的值就是了(通过lowbit实现了不重不漏)
⑤:几个小规律:最外面的节点是2^n,也就是覆盖了最上面所有的(前n个)节点;奇数节点一定是单个节点,偶数节点一定覆盖部分区域;在上述图例中体现了树状数组和原数组之间的关系。我们可以直接记住这个图,人脑可以调动图像化记忆,有助于提高学习效率
⑥:树状数组还有优化的技巧:比如离散化以及这篇的离线操作;不同的题目树状数组所对应的下标也是不同的,有的对应着值,有的对应着原来数组的下标,边学习边补充。
这道题目是求一个区间中<=某个特定的值的数量,给定区间范围i j,小于的数字k,我们按照k从小到大排序,再将a数组从小到大排序,在排序的同时记录下来所有的对应的原本的位置,按照排序的顺序从小到大枚举查询,从小到大枚举a数组,如果a【i】<=k,我们就add这个a[i]原本的位置,剩下的a[i]全部>k就查询,为啥这样可以呢?因为只有这样才能保证我们加上的数字都是有可能在该区间内的且一定比k小的数字这个树状数组的下标存放的是区间段端点。私以为:所谓离线操作就是我们针对查询(输入)进行调整从而更方便处理问题的过程。”离线“这种说法也很形象:在qq上我们收到离线信息,没有跟信息进行即时的交互,同样我们对这些查询也没进行即时的交互,而是对其缓存后续处理,是不是很形象…
看代码,stl熟练使用可以省不少的事情:

#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstdio>
#include<stdlib.h>
#include<map>
#define M 500005
using namespace std;
int wo,wei,a[M],d[M],t[M],n,ming[M];
typedef pair<int,int>pii;
map<int,pii>ma; 
priority_queue<pii,vector<pii>,greater<pii> >qu;
struct node
{
int va,dian;
bool operator<(const node& a)const
{
	return va<a.va; 	
} 	
}node[M];  
int lowbit(int x)
{
	return x&-x;
}
void add(int x)//把包含这个数的结点都更新 
{
	while(x<=M)//范围 
	{
		t[x]++;
		x+=lowbit(x);
	}
}//树状数组的下标必须从1开始 
int sum(int x) 
{
	int res=0;
	while(x>=1)
	{	
		res+=t[x];
		x-=lowbit(x);
	}
	return res;
}
int main()
{   int m; 
	long long ans=0;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
	cin>>a[i];
	node[i].dian=i ;
	node[i].va=a[i];
	} 
	sort(node+1,node+n+1); 
	for(int i=1;i<=m;i++)
	{
		int l,r,zhi;
		scanf("%d%d%d",&l,&r,&zhi);
		qu.push({zhi,i});//i是第几次查询 
		ma[i]={l,r};//第i次查询的左右端点 
	}	int i=1;
	while(qu.size())
	{     
	     wo=qu.top().first; 
		 wei=qu.top().second; 
		 qu.pop();
		 if(i>n)
		 ming[wei]=sum(ma[wei].second)-sum(ma[wei].first-1);  
		 while(i<=n)
		{          
			if(node[i].va<=wo)
			{   
				add(node[i].dian);
				i++;
			}  
			else 
			{
	        ming[wei]=sum(ma[wei].second)-sum(ma[wei].first-1); 
			break;
			}
		}ming[wei]=sum(ma[wei].second)-sum(ma[wei].first-1);
	}
	for(int i=1;i<=m;i++)
	{
		cout<<ming[i]<<endl;
	}
	return 0;
}
 
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-26 09:06:11  更:2021-11-26 09:08:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 16:13:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码