首页 > 其他分享 >树状数组

树状数组

时间:2025-01-21 12:44:27浏览次数:1  
标签:return 树状 int pos long 数组 data size

Question 01 [P3374 树状数组一]
模板题

Code
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+7;
class Tree{
	public:
		inline void scan(long long *_data,int _size){ 
			size=_size;
			for(int i=1;i<=size;i++)_data[i]+=_data[i-1];
			for(int i=1;i<=size;i++)data[i]=_data[i]-_data[i-lowbit(i)];
		}
		inline void modify(int pos,long long key){
			while(pos<=size)data[pos]+=key,pos+=lowbit(pos);
		}
		inline long long query(int pos){
			long long ans=0;
			while(pos>0)ans+=data[pos],pos-=lowbit(pos);
			return ans;
		}
	private:
		int size;
		long long data[N];
		inline int lowbit(int x){
			return x&-x;
		}
}; 
long long lable[N];
Tree tree;
int main(){
	int n,T,op,pos,rim,lim;
	long long key;
	scanf("%d%d",&n,&T);
	for(int i=1;i<=n;i++)scanf("%lld",&lable[i]);
	tree.scan(lable,n);
	while(T--){
		scanf("%d",&op);
		if(op==1){
			scanf("%d%lld",&pos,&key);
			tree.modify(pos,key);
		}else{
			scanf("%d%d",&lim,&rim);
			printf("%lld\n",tree.query(rim)-tree.query(lim-1));
		}
	}
	return 0;
} 

Question 02 [ACP2146 数星星]
二维偏序模板 
大概题意是给定一些点 (x,y) 
对于每个点求横纵坐标不大于该点横纵坐标的点的数量 
即求点(x*, y*) 使得 x*<= x 且 y*<= y 的数量
(点不会重合并且数量不算它自己)
AcCoders 的输入很良心
正常我们需要先排序来解决一维偏序 
其实按哪一维为第一关键字排序都可以
假定我们以 y 为第一关键字排序 

排序 Code
bool cmp(Shit A,Shit B){
	if(A.y==B.y)return A.x<B.x;
	return A.y<B.y; 
} 

接下来我们用树状数组再解决另一维 
我们按顺序遍历每一个点 
首先已经能够确定只要在其前面的都能保证 y* <= y 了
只需再确定 x*<= x 的数量
(由于我们在 y*== y 的时候已经保证 x 单调递增,无需考虑后面的)
接下来用树状数组类似桶排的方式再解决一维
将每一个点的 y 坐标插入树状数组
然后求和即可 
 
Code
#include<bits/stdc++.h>
using namespace std;
const int N=66666;
class Tree{ 
	public:
		inline void modify(int pos,long long key){
			while(pos<=size)data[pos]+=key,pos+=lowbit(pos);
		}
		inline long long query(int pos){
			long long ans=0;
			while(pos>0)ans+=data[pos],pos-=lowbit(pos);
			return ans;
		}
	private:
		int size=33330;
		long long data[N]={};
		inline int lowbit(int x){return x&-x;}
}; 
Tree tree;
int main(){
	int T,x,y;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&x,&y);
		++x;//x maybe zero ,And It will cause INF loops!
		printf("%lld\n",tree.query(x));
		tree.modify(x,1);
	} 
	return 0;
} 

标签:return,树状,int,pos,long,数组,data,size
From: https://www.cnblogs.com/2025ing/p/18683408

相关文章

  • 5、原来可以这样理解C语言_数组
    目录​编辑1.数组的概念2.⼀维数组的创建和初始化2.1数组创建⼀维数组创建的基本语法如下:2.2数组的初始化2.3数组的类型3.⼀维数组的使⽤ 3.1数组下标3.2数组元素的打印3.3数组的输⼊4.⼀维数组在内存中的存储5.sizeof计算数组元素个数6.⼆维数组......
  • 树状数组
    l(x)=x-lowbit(x)+1。即,l(x)是c[x]管辖范围的左端点。对于任意正整数x,总能将x表示成s*2^{k+1}+2^k的形式,其中lowbit(x)=2^k。下面「c[x]和c[y]不交」指c[x]的管辖范围和c[y]的管辖范围不相交,即[l(x),x]和[l(y),y]不相交。「c[x]包含于c[y]」......
  • 剑指offer面试题3:数组中重复的数字(Python实现)
    """面试题3:数组中重复的数字在一个长度为n的数组里所有数字都在0~n-1的范围内,某些数字是重复的,找出任意一个重复的数字"""defduplicate1(numbers:list,length:int)->int:"""修改原数组"""ifnumbers==[]orlength<=0:......
  • java —— 数组(超详细教程)
    介绍:这期讲的是java的原生数组,也就是list(静态空间),空间是写死的;后期的ArrayList是动态数组。我们需要先认识基础的格式,方便后面的ArrayList学习。一、创建数组(一)方法一:1、先声明,再定义长度。publicstaticvoidmain(String[]args){//声明变量int[......
  • C语言逆序操作数组和引用传递参数
    ////main.c//Test_C////Createdbystevexiaohuzhaoon2025/1/20.//#include<stdio.h>//C语言指针传递参数(引用传递)voidswap(int*px,int*py){intt=*px;*px=*py;*py=t;}voidtest(intn){intx=1;for(inti......
  • leetcode349-两个数组的交集
    leetcode349实现利用哈希set进行去重,然后循环nums2,如果nums2中的元素是在去重后的num1中出现过的,就存放在set2中,因为最后要返回的是不重复的数组,所以先放在set2,让其进行去重,最后把set2转为数组方法1varintersection=function(nums1,nums2){constset1=[........
  • PTA 之 数组元素循环右移问题
    一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0​A1​⋯AN−1​)变换为(AN−M​⋯AN−1​A0​A1​⋯AN−M−1​)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?输入格式:......
  • 写一个方法,传入数字x,从一个一维数组里找到两个数字符合“n1 + n2 = x”
    在前端开发中,你可以使用JavaScript来编写这个方法。下面是一个简单的实现,它接受一个数字x和一个一维数组arr作为参数,并尝试在数组中找到两个数字,使它们的和等于x。如果找到了这样的两个数字,它会返回一个包含这两个数字的数组;如果没有找到,它会返回null。functionfindTwoNumbersTh......
  • 树状数组板子(单点增加+范围查询)
    用于解决范围数字和与单点增加问题(复杂度O(logn))build方法(构造树状数组)voidbuild(){ for(inti=1,v;i<=n;i++){ cin>>v; add(i,v); }}lowbit方法(获取一个二进制数最低位的1的状态)intlowbit(intx){ returnx&(-x);}add方法(单点增加)voidadd(inti,int......
  • 代码随想录——动态规划31打家劫舍III(树状DP)
    这道题目是打家劫舍III(HouseRobberIII),是打家劫舍系列问题的变种。问题描述如下:小偷发现了一个新的区域,这个区域的所有房屋排列类似于一棵二叉树。如果两个直接相连的房屋在同一晚被打劫,房屋会自动报警。给定这棵二叉树的根节点root,求在不触发警报的情况下,小偷能够盗取的最......