• 分享
  • 敲了一个最普通的线段树模板,希望对大家有用(如果有错还请大佬直接指出来啦)

  • @ 2022-7-26 22:29:44
// 伪 代 码 不 完 整 
#include<bits/stdc++.h>
#define nl now<<1
#define nr now<<1|1
using namespace std;
const int MAXN=1e6+5;
struct note{
	int left;
	int right;
	int num;
	int lazy;
}tree[MAXN<<2];
int a[MAXN];
int n;
// 快 读 
inline int read()
{
	int x=0,y=1;
	char s=getchar();
	while(s!='-'&&(s<'0'||s>'9'))s=getchar();
	if(s=='-')
	{
		y=-1;
		s=getchar();
	}
	while(s>='0'&&s<='9')x=(x<<1)+(x<<3)+s-'0',s=getchar();
	return x*y;
}
// 懒 标 记 下 传 
inline void down(int now)
{
	if(tree[now].lazy)
	{
		tree[nl].num+=tree[now].lazy*(tree[nl].right-tree[nl].left+1);
		tree[nr].num+=tree[now].lazy*(tree[nr].right-tree[nr].left+1);
		tree[nl].lazy+=tree[now].lazy;
		tree[nr].lazy+=tree[now].lazy;
		tree[now].lazy=0;
	}
	return;
}
// 建 树 
inline void build(int l,int r,int now)
{
	tree[now].left=l;
	tree[now].right=r;
	if(l==r)
	{
		tree[now].num=a[l];
		return;
	}
	int mid=(tree[now].left+tree[now].right)>>1;
	build(l,mid,nl);
	build(mid+1,r,nr);
	tree[now].num=tree[nl].num+tree[nr].num;
	return;
}
// 区 间 查 询 
inline int ask(int l,int r,int now)
{
	if(l<=tree[now].left&&r>=tree[now].right)
		return tree[now].num;
	down(now);
	int mid=(tree[now].left+tree[now].right)>>1;
	int val=0;
	if(l<=mid)val+=ask(l,r,nl);
	if(r>mid)val+=ask(l,r,nr);
	return val;
}
// 单 点 修 改 
inline void changes(int set,int value,int now)
{
	if(tree[now].left==tree[now].right)
	{
		tree[now].num=value;
		return;
	}
	int mid=(tree[now].left+tree[now].right)>>1;
	if(set<=mid)changes(set,value,nl);
	else changes(set,value,nr);
	tree[now].num=tree[nl].num+tree[nr].num;
	return;
}
// 区 间 加 减 
inline void change(int l,int r,int add,int now)
{
	if(l<=tree[now].left&&r>=tree[now].right)
	{
		tree[now].num+=add*(tree[now].right-tree[now].left+1);
		tree[now].lazy+=add;
		return;
	}
	down(now);
	int mid=(tree[now].left+tree[now].right)>>1;
	if(l<=mid)change(l,r,add,nl);
	if(r>mid)change(l,r,add,nr);
	tree[now].num=tree[nl].num+tree[nr].num;
	return;
}
int main()
{
	n=read();			// 原 数 组 长 度 
	for(int i=1;i<=n;i++)
		a[i]=read();	// 数 组 单 点 值 
// 建 树 
	build(1,n,1);
// 区 间 查 询 
	ask(__,__,1);		// 左 边 界 ,右 边 界 
// 单 点 修 改 
	changes(__,__,1);	// 单 点 位 置 ,修 改 值 
// 区 间 加 减 
	change(__,__,__,1);	// 左 边 界 ,右 边 界 ,加 减 值 
	return 0;
}

3 条评论

  • 1