首页 > 其他分享 >「线段树」笔记

「线段树」笔记

时间:2023-11-23 20:44:25浏览次数:25  
标签:rp cdot 线段 笔记 fa int tag sum

基础

建树

void build(int p, int l, int r)
{
	t[p] = (tree){l, r, 0};
	if (l == r)
	{
		t[p].sum = val[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(lp, l, mid);
	build(rp, mid + 1, r);
	pushup(p);
}

单点修改(和)

void update(int p, int x, int k)
{
	if (t[p].l == x && t[p].r == x)
	{
		t[p].sum += k;
		return;
	}
	int mid = (t[p].l + t[p].r) >> 1;
	if (x <= mid) update(lp, x, k);
	if (x > mid) update(rp, x, k);
	pushup(p);
}

区间修改 + lazy tag(和)

void pushdown(int p)
{
	if (t[p].tag)
	{
		t[lp].sum += (t[lp].r - t[lp].l + 1) * t[p].tag;
		t[rp].sum += (t[rp].r - t[rp].l + 1) * t[p].tag;
		t[lp].tag += t[p].tag;
		t[rp].tag += t[p].tag;
		t[p].tag = 0;
	}
}

void update(int p, int l, int r, ll k)
{
	if (l <= t[p].l && t[p].r <= r)
	{
		t[p].sum += (ll)(t[p].r - t[p].l + 1) * k;
		t[p].tag += k;
		return;
	}
	pushdown(p);
	int mid = (t[p].l + t[p].r) >> 1;
	if (l <= mid) update(lp, l, r, k);
	if (r > mid) update(rp, l, r, k);
	pushup(p);
}

区间查询(和)

int query(int p, int l, int r)
{
	if (l <= t[p].l && t[p].r <= r)
		return t[p].sum;
	//pushdown(p); <--- 区间修改
	int mid = (t[p].l + t[p].r) >> 1;
	int ans = 0;
	if (l <= mid) ans += query(lp, l, r);
	if (r > mid) ans += query(rp, l, r);
	return ans;
}

区间乘加 + 区间和查询

则线段树需要维护的节点信息有:区间和 \(sum\),乘法和加法分别的懒标记 \(tag_{mul},~tag_{add}\)

此时讨论加法和乘法的优先级,push_up 仍为求和,考虑 push_down

  • 当加法优先时

对于该节点 \(p\) ,有懒标记 \(p_m,~p_a\),且有父节点 \(fa\),懒标记 \(fa_m, ~fa_a\)

则对于 \(p\) 区间上的任意一个 \(x\),要把它转化为和积的形式,有:

\[\begin{aligned} x&=\{~[~(x+p_a)\times p_m ] + fa_a \} \times fa_m\\ &=(x\cdot p_m + p_a\cdot p_m + fa_a ) \times fa_m\\ &=x\cdot p_m \cdot fa_m + p_a\cdot p_m\cdot fa_m + fa_a\cdot fa_m\\ &= p_m\cdot fa_m~(x + p_a +\frac{fa_a}{p_m}) \end{aligned} \]

得到新的 \(p^\prime_a = p_a +\frac{fa_a}{p_m},~ p^\prime_m = p_m\cdot fa_m\),但是 \(p_a^\prime\) 可能不是整数,会损失精度,不成立。

  • 当乘法优先时

同理有:

\[\begin{aligned} x &= (x\cdot p_m + p_a)\times fa_m +fa_a\\ &= x\cdot p_m\cdot fa_m + p_a \cdot fa_m + fa_a \end{aligned} \]

得到新的 \(p^\prime_a = p_a \cdot fa_m + fa_a,~ p^\prime_m = p_m\cdot fa_m\) ,成立。

那么,得到乘法优先可行,考虑具体更新当前点 \(p\) 的区间 \([l,r]\),则有:

\[\begin{aligned} sum &= \sum\limits_{i=l}^r\Big(p_i\cdot p_m + p_a\Big)\\ &= \sum\limits_{i=l}^r p_i \cdot p_m + (r-l+1)\cdot p_a\\ &= sum\cdot p_m + (r-l+1)\cdot p_a \end{aligned} \]

void count(int p, ll m, ll a)
{
	t[p].sum = (t[p].sum * m % mod + (t[p].r - t[p].l + 1) * a % mod) % mod;
	t[p].mul = t[p].mul * m % mod;
	t[p].add = (t[p].add * m % mod + a) % mod;
}

void pushdown(int p)
{
	count(lp, t[p].mul, t[p].add);
	count(rp, t[p].mul, t[p].add);
	t[p].mul = 1;
	t[p].add = 0;
}

标签:rp,cdot,线段,笔记,fa,int,tag,sum
From: https://www.cnblogs.com/hi-zwjoey/p/17851323.html

相关文章

  • 11月21号课堂笔记
    1.插入排序#include"stdio.h"#defineN5intmain(){ //12345 //21345 inta[N]={1,2,3,4,5},i,j,tmp; for(i=1;i<N;i++) { j=i-1; tmp=a[i]; while(a[j]<tmp&&j>=0){ a[j+1]=a[j]; j--; } a[j+1]=tmp; } for(i=0;......
  • 【模板】可持久化线段树 2
    【模板】可持久化线段树2题目背景这是个非常经典的可持久化权值线段树入门题——静态区间第$k$小。数据已经过加强,请使用可持久化权值线段树。同时请注意常数优化。题目描述如题,给定$n$个整数构成的序列$a$,将对于指定的闭区间$[l,r]$查询其区间内的第$k$小值。输......
  • openGauss学习笔记-131 openGauss 数据库运维-启停openGauss
    openGauss学习笔记-131openGauss数据库运维-启停openGauss131.1启动openGauss以操作系统用户omm登录数据库主节点。使用以下命令启动openGauss。gs_om-tstart说明:双机启动必须以双机模式启动,若中间过程以单机模式启动,则必须修复才能恢复双机关系,用gs_ctlbuild进......
  • 看番笔记
    重看《吹响!上低音号!》第四话仿佛在诉说着“这种无聊的事根本无所谓”一般,高坂同学的小号声在空中回荡。很难不想到高中的跑操。“这样做有什么意义呢?”的声音不绝于耳。但是进到下一步后,又会出现新的问题,不管练几次都无法完美这个道理我目前还没有什么属于自己的感悟。......
  • Springboot文件上传代码笔记
    1.在src下创建filter包,包内Class名UploadFilterpackagecom.gd.filter;importorg.apache.catalina.servlet4preview.http.HttpServletRequest;importjavax.servlet.*;importjavax.servlet.annotation.WebFilter;importjavax.servlet.http.HttpServletResponse;impor......
  • 刘金玉QT学习笔记:7-简易用户信息管理界面实现_实现用户信息增改
    1.同第六课方式在widget里连接并创建数据库。 2.通过QSqlQuery使用sql语句的第二种方法:-在不同的函数中都要使用->做成全局变量 3.表格网格控件tableview控件显示数据库的内容为表格行-ui拖出控件-qtableview控件通过QSqlQueryModel来渲染数据过程:1widget.h引入#i......
  • 学习笔记11—20211303
    一、学习任务自学教材第13章,提交学习笔记(10分),评分标准如下1.知识点归纳以及自己最有收获的内容,选择至少2个知识点利用chatgpt等工具进行苏格拉底挑战,并提交过程截图,提示过程参考下面内容(4分)“我在学***X知识点,请你以苏格拉底的方式对我进行提问,一次一个问题”核心是要求GPT:......
  • Golang学习笔记-自定义日志轮转及输出
    packagepkgimport( "fmt" "log" "log/slog" "os" "time")varcontrolLogger*slog.LoggervarfileLogger*slog.Loggerconst( timeFormat="2006-01-02")funcInitLog(filepathstring){......
  • 秦疆的Java课程笔记:37 流程控制 switch选择结构
    多选择结构还有一个实现方式就是switchcase语句。switchcase语句判断一个变量与一系列值中某个值是否相等,每个值为一个分支。if判断区间,switch匹配一个具体的值。语法:switch(expression){ casevalue: //语句 break;//可选 casevalue: //语句 break;//可选 ......
  • FPGA入门笔记006——状态机设计实例
    状态分析:状态1:等待“H”的到来,如果检测到“H”,进入状态2,检测“e”,否则一直等待“H”;状态2:检测当前字符是否是“e”,如果是“e”,跳转到状态3,检测“l”,否则,回到状态1,重新等待“H”;状态3:检测当前字符是否是“l”,如果是“l”,跳转到状态4,检测“l”,否则,回到状态1,重新等待“H”;状态4:......