模板积累——线段树建树,修改,查找,延迟更新

本文深入探讨线段树的数据结构,详细解释了线段树的构造过程,包括如何进行初始建树,以及在动态更新数据时如何维护线段树的正确性。同时,阐述了线段树的查找操作和延迟更新策略,以实现高效的数据查询和修改。
摘要由CSDN通过智能技术生成
#include <bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int M=100100;
ull tree[4*M];//数的节点数要开叶子节点的四倍
ull lazy[4*M];
ull a[M];
int n;
void pushdown(int rt,int m){
	if(lazy[rt]){
		lazy[rt*2]=lazy[rt*2+1]=lazy[rt];
		tree[rt*2]=(m-m/2)*lazy[rt];
		tree[rt*2+1]=(m/2)*lazy[rt];
		lazy[rt]=0;
	}
}
void build(int l,int r,int rt){
	lazy[rt]=0;//初始化lazy标记	
	if(l==r){//到达叶子节点
		tree[rt]=a[l];
		return;
	}
	int m=(l+r)/2;
	build(l,m,rt*2);
	build(m+1,r,rt*2+1);
	//向下递归开树
	//tree[rt]=tree[rt*2]+tree[rt*2+1];回溯时根据题意填写回溯信息
}
ull find1(int l,int r,int rt,int L,int R){//查询
	if(l>=L&&r<=R){
		return tree[rt];
	}
	pushdown(rt,r-l+1);//更新
	int m=(l+r)/2;
	ull temp=0;
	if(L<=m){
		//temp=temp+find1(l,m,rt*2,L,R);
	}
	if(R>m){
		//temp=temp+find1(m+1,r,rt*2+1,L,R);
	}
	return temp; //返回值取值方法由题意决定
}
void xiugai(int l,int r,int rt,int x,int y,int z){//x,y为区间,z为修改信息
	if(x<=l&&r<=y) {
		//tree[rt]=z*(r-l+1);更新,方式由题意决定
		//lazy[rt]=z;添加lazy标记,方式由题意决定 
		return;
	}
	pushdown(rt,r-l+1);//更新
	if(l==r){
		tree[rt]=z;
		//printf("%d",tree[rt]);
		return ;
	}
	int m=(l+r)/2;
	if(x<=m){
		xiugai(l,m,rt*2,x,y,z);
	}
	if(y>m){
		xiugai(m+1,r,rt*2+1,x,y,z);
	}
	//区间修改递归
	//tree[rt]=tree[rt*2]+tree[rt*2+1];回溯,回溯信息由题目决定
}
int main(){
	int k=0;
	while(~scanf("%d",&n)){
		printf("Case #%d:\n",++k);
		for(int i=1;i<=n;i++){
			scanf("%llu",a+i);
		}
		/*int m;
		scanf("%d",&m);*/
		build(1,n,1);//建树
		/*int cmd;
		int x,y;
		while(m--){
			scanf("%d%d%d",&cmd,&x,&y);
			if (x>y)swap(x,y);
			if(cmd!=1){
				if(find1(1,n,1,x,y)!=y-x+1){
					xiugai(1,n,1,x,y); 
				}
			}
			if(cmd==1){
				printf("%llu\n",find1(1,n,1,x,y));
			}
		}
		printf("\n");*/
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值