线段树模板

线段树单点

const int maxn = 500005 * 4;	//线段树范围要开4倍
struct Tree
{
	int l, r, sum, maxx;
};
Tree node[maxn];		//node[maxn]为线段树处理数组
int a[maxn];			//a[maxn]为原数组
void PushUp(int i)
{
	node[i].sum = node[i << 1].sum + node[(i << 1) | 1].sum;
	node[i].maxx = max(node[i << 1].maxx, node[(i << 1) | 1].maxx);
}
void build(int i, int l, int r)
{
	node[i].l = l; node[i].r = r;
	if (l == r)
	{
		node[i].maxx = a[l];
		node[i].sum = a[l];
		return;
	}
	int mid = (l + r) / 2;
	build(i << 1, l, mid);
	build((i << 1) | 1, mid + 1, r);
	PushUp(i);
}
int getsum(int i, int l, int r)
{
	if (node[i].l == l&&node[i].r == r)
		return node[i].sum;
	int mid = (node[i].l + node[i].r) / 2;
	if (r <= mid) return getsum(i << 1, l, r);
	else if (l > mid) return getsum((i << 1) | 1, l, r);
	else return getsum(i << 1, l, mid) + getsum((i << 1) | 1, mid + 1, r);
}
int getmax(int i, int l, int r)
{
	if (node[i].l == l&&node[i].r == r)
		return node[i].maxx;
	int mid = (node[i].l + node[i].r) / 2;
	if (r <= mid) return getmax(i << 1, l, r);
	else if (l>mid) return getmax((i << 1) | 1, l, r);
	else return max(getmax(i << 1, l, mid), getmax((i << 1) | 1, mid + 1, r));
}
void add(int i, int k, int v)	        //当前更新的节点的编号为i(一般是1为初始编号,具体得看建立树时使用的第一个编号是什么)。
{								//k为需要更新的点的位置,v为修改的值的大小
	if (node[i].l == k&&node[i].r == k)        //左右端点均和k相等,说明找到了k所在的叶子节点
	{
		node[i].sum += v;
		node[i].maxx += v;
		return;    //找到了叶子节点就不需要在向下寻找了
	}
	int mid = (node[i].l + node[i].r) / 2;
	if (k <= mid) add(i << 1, k, v);
	else add((i << 1) | 1, k, v);
	PushUp(i);
}

void update(int i, int k, int v)	        //当前更新的节点的编号为i(一般是1为初始编号,具体得看建立树时使用的第一个编号是什么)。
{								//k为需要更新的点的位置,v为修改的值的大小
	if (tree[i].l == k&&tree[i].r == k)        //左右端点均和k相等,说明找到了k所在的叶子节点
	{
		tree[i].sum = v;
		tree[i].maxx = v;
		return;    //找到了叶子节点就不需要在向下寻找了
	}
	int mid = (tree[i].l + tree[i].r) / 2;
	if (k <= mid) update(i << 1, k, v);
	else update((i << 1) | 1, k, v);
	PushUp(i);
}

线段树区间

const int N = 100005;
LL a[N];					//a[N]储存原数组
LL  lazy[N << 2];			//lazy用来记录该节点的每个数值应该加多少 
int n, q;
struct Tree
{
	int l, r;
	LL sum;
	int mid()
	{
		return (l + r) >> 1;
	}
}tree[N<<2];		
 
void PushUp(int rt)
{
	tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
}
 
void PushDown(int rt,int m)
{
	if (lazy[rt])
	{
		lazy[rt << 1] += lazy[rt];
		lazy[rt << 1 | 1] += lazy[rt];
		tree[rt << 1].sum += lazy[rt] * (m - (m >> 1));
		tree[rt << 1 | 1].sum += lazy[rt] * (m >> 1);
		lazy[rt] = 0;
	}
}
 
void build(int l, int r, int rt)
{
	tree[rt].l = l;
	tree[rt].r = r;
	lazy[rt] = 0;
	if (l == r)
	{
		tree[rt].sum = a[l];
		return;
	}
	int m = tree[rt].mid();
	build(l, m, (rt << 1));
	build(m + 1, r, (rt << 1 | 1));
	PushUp(rt);
}
 
void update(LL c, int l, int r, int rt)
{
	if (tree[rt].l == l&&tree[rt].r==r)
	{ 
		lazy[rt] += c;
		tree[rt].sum += c*(r - l + 1);
		return;
	}
	if (tree[rt].l == tree[rt].r)return;
	int m = tree[rt].mid();
	PushDown(rt, tree[rt].r - tree[rt].l + 1);
	if (r <= m)update(c, l, r, rt << 1);
	else if (l > m)update(c, l, r, rt << 1 | 1);
	else 
	{
		update(c, l, m, rt << 1);
		update(c, m + 1, r, rt << 1 | 1);
	}
	PushUp(rt);
}
 
LL Query(int l, int r, int rt)
{
	if (l == tree[rt].l&&r == tree[rt].r)
	{
		return tree[rt].sum;
	}
	int m = tree[rt].mid();
	PushDown(rt, tree[rt].r - tree[rt].l + 1);
	LL res = 0;
	if (r <= m)res += Query(l, r, rt << 1);
	else if (l > m)res += Query(l, r, rt << 1 | 1);
	else
	{
		res += Query(l, m, rt << 1);
		res += Query(m + 1, r, rt << 1 | 1);
	}
	return res;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值