线段树
本文最后更新于297 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

线段树是一种基于分治思想的二叉树结构,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。通过构建线段树,可以在对数时间复杂度内对任意区间进行查询和修改操作。

#include<iostream>
using namespace std;
const int N = 5e5+7;
int n = 8,m,s,t;
int ans;
int a[N] = {0, 4, 5, 6, 2, 1, 3, 7, 8};
struct node{
	int r,l,sum,lazy;
}tree[N*4];
void push_down(int rt)
{
	int &x = tree[rt].lazy;
	if(x)
	{
		tree[rt<<1].lazy += x, 	tree[rt<<1|1].lazy += x;
		tree[rt<<1].sum += (tree[rt<<1].r - tree[rt<<1].l + 1) * x;
		tree[rt<<1|1].sum += (tree[rt<<1|1].r - tree[rt<<1|1].l + 1) * x;
		x = 0;
	}
}
void build(int l, int r, int rt)
{
	tree[rt].l = l,tree[rt].r = r,tree[rt].lazy = 0;
	if(r==l)
	{
		tree[rt].sum = a[l];
		return ;
	}
	int mid =(l+r)>>1;
	build(l, mid, rt<<1);
	build(mid+1, r, rt<<1|1);
	tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
}
void update(int rt, int pos, int val)
{
	int l = tree[rt].l, r = tree[rt].r;
	if(l == r) 	{
		tree[rt].sum+=val;
		return ;
	}
	int mid = (l+r)>>1;
	if(pos <= mid)
		update(rt<<1, pos, val);
	else
		update(rt<<1|1, pos, val);
	tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
}
void add(int l, int r, int rt, int val)
{
	int L = tree[rt].l, R = tree[rt].r;
	if(l <= L && r >= R)
	{
		tree[rt].sum += val;
		tree[rt].lazy += val;
		return ;
	}
	/**/push_down(rt)/**/;
	int mid = (L+R) >>1;
	if(l <= mid) add(l, r, rt<<1, val);
	if(r > mid) add(l, r, rt<<1|1, val);
	tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
}
int search(int l, int r, int rt)
{
	if(l <= tree[rt].l && r >= tree[rt].r)
	{
    	return tree[rt].sum;
	}	
	/**/push_down(rt);/**/
	int mid = (tree[rt].l + tree[rt].r) >> 1, res = 0 ;
	if(l <= mid) res += search(l, r, rt<<1);
	if(r > mid) res += search(l, r, rt<<1|1);
	return res;
}

int main(){

	build(1,n,1);
	update(1,5,1);
	add(1,2,1,2);
	cout<<search(1,8,1)<<endl;
	return 0;
}
如果觉得本文对您有所帮助,那这将是对我最大的鼓励,期待您留下您宝贵的评论。
暂无评论

发送评论 编辑评论


				
上一篇
下一篇