首页 > 其他分享 >线段树(板子)

线段树(板子)

时间:2024-02-19 18:00:30浏览次数:20  
标签:rt return int res 线段 tr mid 板子

线段树

  • 单点修改,单点,区间查询
  • 区间修改,单点,区间查询

单点修改

普通线段树

code
#define ls (rt << 1)
#define rs (rt << 1 | 1)
#define lll long long
const int N = 1000001;
int n,m;
int a[N];
struct T
{
	int l,r,data;
} tr[N<<2];
void pushup(int rt)
{
	tr[rt].data=tr[ls].data+tr[rs].data;
}
void bui(int rt,int l,int r)
{
	tr[rt].l=l; tr[rt].r=r;
	if(l==r)
	{
		tr[rt].data=a[l];
		return;//注意return
	}
	int mid=((lll)l+r)>>1;//注意long long
	bui(ls,l,mid); bui(rs,mid+1,r);
	pushup(rt);
}
void mdf(int rt,int x,int v)
{
	if(tr[rt].l==tr[rt].r)
	{
		tr[rt].data+=v;
		return;
	}
	int mid=((lll)tr[rt].l+tr[rt].r)>>1;
	if(x<=mid) mdf(ls,x,v);
	else mdf(rs,x,v);
	pushup(rt);
}
int que(int rt,int l,int r)
{
	if(l<=tr[rt].l&&r>=tr[rt].r)
		return tr[rt].data;
	int mid=((lll)tr[rt].l+tr[rt].r)>>1;
	int res=0;
	if(l<=mid) res+=que(ls,l,r);
	if(r>mid) res+=que(rs,l,r);
	return res;
}

区间修改

“卤煮”存一下更新,查询时再下放。

code
#define lll long long
#define ls (rt << 1)
#define rs (rt << 1 | 1)
const int N = 100005;
int n,a[N],m;
struct T
{
	int l,r,data,lz;
} tr[N<<2];
void pushup(int rt)
{
	tr[rt].data=tr[ls].data+tr[rs].data;
}
void pushdown(int rt)
{
	if(tr[rt].lz!=0)
	{
		int lz=tr[rt].lz;
		tr[rt].lz=0;
		tr[ls].lz+=lz;
		tr[rs].lz+=lz;
		tr[ls].data+=lz*(tr[ls].r-tr[ls].l+1);
		tr[rs].data+=lz*(tr[rs].r-tr[rs].l+1);
	}
}
void bui(int rt,int l,int r)
{
	tr[rt].l=l; tr[rt].r=r;
	if(l==r)
	{
		tr[rt].data=a[l];
		return ;
	}
	int mid=((lll)l+r)>>1;
	bui(ls,l,mid); bui(rs,mid+1,r);
	pushup(rt);
}
void mdf(int rt,int l,int r,int v)
{
	if(l<=tr[rt].l&&r>=tr[rt].r)
	{
		tr[rt].lz+=v;
		tr[rt].data+=v*(tr[rt].r-tr[rt].l+1);
		return;
	}
	int mid=((lll)tr[rt].l+tr[rt].r)>>1;
	if(l<=mid) mdf(ls,l,r,v);
	if(r>mid) mdf(rs,l,r,v);
	pushup(rt);
}
int que(int rt,int l,int r)
{
	if(l<=tr[rt].l&&r>=tr[rt].r)
		return tr[rt].data;
	pushdown(rt);
	int mid=((lll)tr[rt].l+tr[rt].r)>>1;
	int res=0;
	if(l<=mid) res+=que(ls,l,r);
	if(r>mid) res+=que(rs,l,r);
	return res;
}

线段树就是打心态。

标签:rt,return,int,res,线段,tr,mid,板子
From: https://www.cnblogs.com/ppllxx/p/18021610

相关文章

  • 线段树-基础模版
    线段树模版一埋头扎进线段树一上午感觉很神奇几个函数就能把它完整的复现下来这里有几张基础概念的图对着代码来想还是很好理解的最后是整理了能够处理总和最大值和最小值的线段树模版code:$\LARGE\color{purple}{代码在这里}$#include<bits/stdc++.h>usingnames......
  • 树状数组及线段树详解
    本文章是作者调了3个多小时后,感触颇深,历经1个多小时写出来的,不喜勿喷相关内容可参考模板总结中的树状数组及线段树;进入正题树状数组所谓树状数组,即像树的数组,一般应用于求多次前缀和以及区间前缀和的问题中;其根据节点编号的二进制数的末尾0的个数划分层次,每个节点的管辖......
  • 嵌入式学习(五)要买的板子
    51单片机:arduinomicro板子加上外围才20+,很便宜冯诺依曼结构的瓶颈:由于存储器速度很慢,CPU只能被迫等待存储器读写数据,因此遏制了CPU的吞吐量,限制了计算机速度。冯·诺依曼瓶颈的概念最早由JohnBackus在1977年的图灵奖领奖演讲中提出:由于CPU和存储器之间共享同一个系统总......
  • 线段树进阶
    线段树进阶动态开点定义动态存储数据的线段树,可以优化空间复杂度实现为了避免\(N<<1\),不再使用完全二叉树存储,而记录左右儿子\(ls,rs\)此外需要\(tot\)记录已经开了多少点在递归时要记录点的左右区间,确保开点时能知道区间大小voidmodify(int&p,intL,intR,intl,i......
  • 线段树进阶
    线段树进阶线段树分治P5787判断二分图可以用扩展域并查集,采用线段树分治,线段树上的每一个结点作为每一段时间。每个结点上的修改和回溯需要用到可撤销的并查集。时间复杂度\(O(n\logk\logn)\)扫描线扫描线求矩形面积#include<bits/stdc++.h>usingnamespacestd;typ......
  • 线段树
    【前置知识】运算律,单位元。运算律基本就是交换律、结合律、分配律。单位元:假设我们现在有一个运算\(\bigoplus\)。如果\(a\bigoplusb=b\bigoplusa=a\),称\(b\)是运算\(\bigoplus\)的单位元。【线段树】线段树是一个树形数据结构。满二叉树;倍增的思想,分治的手......
  • 李超线段树
    李超线段树线段树的扩展版本用来动态维护平面上直线支持插入直线/线段,查询横坐标某处覆盖的线中纵坐标最大/最小值可以用于斜率优化DP插入直线这里直线是线段树上维护的信息,表示当前区间中点处最优的直线同时相当于区间修改,直线也是标记,这个区间内都可能有这条直线但是标......
  • 2024.2.14 WC24 线段树 / CF1572D / lgP3679
    西安Day1。感冒还没好,牙龈炎也没好,明天还要考试,又要坐牢了/kk。今天是tyy的图论选讲,感觉前面网络流部分还是在线的,平面图部分毒瘤tyy拿出了他的员交课件,恐怖,直接下线了。看了NAVI和Faze的预选赛,你们俩怎么都打的这么稀碎/fn。Override真好听。「WC2024」线段树我......
  • 线段树分治学习笔记
    线段树分治线段树分治是一种可以离线处理带撤销问题的常用手段。一般而言,题目中加入操作很好维护,但删除操作不好维护,这时可以对时间维建线段树,把每一个操作加入其存在时间段对应的线段树节点上,然后处理所有询问,进入一个节点时将这个节点里的操作加入,递归左右儿子,然后撤销这一次做......
  • 线段树进阶奇淫巧计
    看本文文字部分可以少带脑子,但是代码部分仔细看了因为不一定编译了不一定对动态开点一般来说线段树的空间开销是比较巨大的,需要\(4n\)的空间,一般其实是可以支撑的,但是权值线段树就不一定了。值域级别的代价是支持不了的。一般在动态开点的前提下只需要支持单点操作一旦是序......