线段树是一种基于分治思想的二叉树结构,用于在区间上进行信息统计。

  1. 线段树的每个节点都代表一个区间
  2. 线段树具有唯一的根节点,代表的区间是整个统计范围,如[1,n]
  3. 线段树的每个叶节点都代表一个长度为1的元区间
  4. 对于每个内部节点[l,r],它的左子节点是[l,mid],右子节点是[mid+1,r],其中mid=(l+r)>>1

线段树的建树

void build(int rt,int l,int r){
	tree[rt].l=l;
	tree[rt].r=r;
	if(l==r){
		tree[rt].sum=tree[rt].max=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	tree[rt].sum=tree[lson].sum+tree[rson].sum;
	tree[rt].max=max(tree[lson].max,tree[rson].max);
}
    build(1,1,n);//调用入口

线段树的单点修改

void update(int rt,int pos,int val){
	if(tree[rt].l==tree[rt].r){
		tree[rt].sum+=val;
		tree[rt].max=val;
		return;
	}
	int mid=(tree[rt].l+tree[rt].r)>>1;
	if(pos<=mid) update(lson,pos,val);
	else update(rson,pos,val);
	tree[rt].sum=tree[lson].sum+tree[rson].sum;
	tree[rt].max=max(tree[lson].max,tree[rson].max);
}
update(1,pos,val);//调用入口

线段树的区间查询

int query(int rt,int l,int r){
    if(l<=tree[rt].l&&tree[rt].r<=r) return tree[rt].sum;
    int mid=(tree[rt].l+tree[rt].r)>>1;
    if(r<=mid) return query(lson,l,r);
    if(l>mid) return query(rson,l,r);
    else return query(lson,l,r)+query(rson,l,r);
}
cout<<query(1,l,r)<<endl;//调用入口 

 

posted on 2024-02-20 19:22  风ffff  阅读(18)  评论(0编辑  收藏  举报