线段树上树剖再拿线段树维护:0914T4

news2024/12/23 14:28:27

cp

一种常见套路:

如果在线段树上进行一段区间修改,那么必然是一段右节点+一段左节点

这个过程其实就是zkw的本质

下面都要用zkw来理解

考虑原题,有一棵不规则的线段树

类似zkw,在这类题目中,我们要先把开区间变成闭区间

然后每个点记录其兄弟节点的信息

考虑现在区间为 ( x , y ) (x,y) (x,y),我们可以先求出其 z = l c a ( x , y ) z=lca(x,y) z=lca(x,y)

x x x 要跳到 l s [ z ] ls[z] ls[z] y y y 要跳到 r s [ z ] rs[z] rs[z]

x x x 在跳的过程中,如果它是左节点那么就修改/统计它的右节点

我们可以回顾zkw的过程帮助理解:

在这里插入图片描述
然后现在考虑优化跳的这个过程。

我们发现这就是个树剖。

然后就完成啦

时间复杂度 O ( n log ⁡ 2 n ) O(n\log^2n) O(nlog2n)

线段树套线段树

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'||
ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define Z(x) (x)*(x)
#define pb push_back

#define N 400010
int n, m, i, j, k, T;
int f[N][22], q, x, y, ans, dep[N], lxy, op, d, mp[N]; 

struct Segment_tree {
	int tot, ls[N<<1], rs[N<<1], rt; 
	int s[N<<1], tag[N<<1], len[N<<1]; 
	void build(int &k, int l, int r) {
		if(!k) k=++tot; 
		if(l==r) return ; 
		int mid=(l+r)>>1; 
		build(ls[k], l, mid); 
		build(rs[k], mid+1, r); 
	}
	void make(int k, int l, int r, int x, int y) {
		if(l==r) return len[k]=y, void(); 
		int mid=(l+r)>>1; 
		if(x<=mid) make(ls[k], l, mid, x, y); 
		else make(rs[k], mid+1, r, x, y); 
		len[k]=len[ls[k]]+len[rs[k]]; 
	}
	void add(int k, int l, int r, int x, int y, int z) {
		if(l>=x && r<=y) {
			tag[k]+=z; s[k]+=len[k]*z; 
			return ; 
		}
		tag[ls[k]]+=tag[k]; s[ls[k]]+=len[ls[k]]*tag[k]; 
		tag[rs[k]]+=tag[k]; s[rs[k]]+=len[rs[k]]*tag[k]; 
		tag[k]=0; 
		int mid=(l+r)>>1;  
		if(x<=mid) add(ls[k], l, mid, x, y, z); 
		if(y>=mid+1) add(rs[k], mid+1, r, x, y, z); 
		s[k]=s[ls[k]]+s[rs[k]]; 
	}
	int que(int k, int l, int r, int x, int y) {
		if(l>=x && r<=y) return s[k]; 
		int mid=(l+r)>>1, sum=0; 
		tag[ls[k]]+=tag[k]; s[ls[k]]+=len[ls[k]]*tag[k]; 
		tag[rs[k]]+=tag[k]; s[rs[k]]+=len[rs[k]]*tag[k]; 
		tag[k]=0; 
		if(x<=mid) sum+=que(ls[k], l, mid, x, y); 
		if(y>=mid+1) sum+=que(rs[k], mid+1, r, x, y); 
		return sum; 
	}
}S1, S2;

struct Tree_chain_pou_score {
	int ls[N], rs[N], tot; 
	int w[N], st[N], ed[N], len[N]; 
	int up[N], dfn[N], p[N]; 
	int son[N], ltson[N]; 
	void dfs1(int x) {
		if(x<=n) {
			st[x]=ed[x]=x; w[x]=1; 
			return ; 
		}
		f[ls[x]][0]=f[rs[x]][0]=x; 
		dep[ls[x]]=dep[rs[x]]=dep[x]+1; 
		dfs1(ls[x]); dfs1(rs[x]); 
		st[x]=st[ls[x]]; ed[x]=ed[rs[x]]; 
		w[x]=w[ls[x]]+w[rs[x]]+1; 
	}
	void dfs2(int x, int Up) {
		up[x]=Up; dfn[x]=++tot; p[x]=tot;  
		len[x]=ed[x]-st[x]+1; 
		if(x<=n) return ; 
		if(w[ls[x]]>w[rs[x]]) son[x]=ls[x], ltson[x]=rs[x]; 
		else son[x]=rs[x], ltson[x]=ls[x]; 
		dfs2(son[x], Up); 
		dfs2(ltson[x], ltson[x]); 
		S1.make(1, 1, m, dfn[ls[x]], len[rs[x]]); 
		S2.make(1, 1, m, dfn[rs[x]], len[ls[x]]); 
	}
	void add(Segment_tree &Seg, int x, int y, int z) {
		while(up[x]!=up[y]) {
			Seg.add(1, 1, m, dfn[up[x]], dfn[x], z); 
			x=f[up[x]][0]; 
		}
		if(x==y) return ; 
		Seg.add(1, 1, m, dfn[y]+1, dfn[x], z); 
	}
	int que(Segment_tree &Seg, int x, int y) {
		int ans=0; 
		while(up[x]!=up[y]) {
			ans+=Seg.que(1, 1, m, dfn[up[x]], dfn[x]); 
			x=f[up[x]][0]; 
		}
		if(x==y) return ans; 
		ans+=Seg.que(1, 1, m, dfn[y]+1, dfn[x]); 
		return ans; 
	}
}Tree;

int lca(int x, int y) {
	if(x==y) return x; 
	if(dep[x]<dep[y]) swap(x, y); 
	for(int k=20; k>=0; --k)
		if(dep[f[x][k]]>=dep[y]) x=f[x][k]; 
	if(x==y) return x; 
	for(int k=20; k>=0; --k)
		if(f[x][k]!=f[y][k]) x=f[x][k], y=f[y][k]; 
	return f[x][0]; 
}

signed main()
{
	freopen("pigeons.in", "r", stdin);
	freopen("pigeons.out", "w", stdout);
	n=read(); q=read(); 
	for(i=n+1; i<2*n; ++i) {
		Tree.ls[i+2]=read(); Tree.rs[i+2]=read(); 
		if(Tree.ls[i+2]<=n) Tree.ls[i+2]++; 
		else Tree.ls[i+2]+=2; 
		if(Tree.rs[i+2]<=n) Tree.rs[i+2]++; 
		else Tree.rs[i+2]+=2; 
		mp[Tree.ls[i+2]]=mp[Tree.rs[i+2]]=1; 
	}
	for(i=n+3; mp[i]; ++i); 
	Tree.ls[2*n+2]=1; Tree.rs[2*n+2]=i; 
	Tree.ls[2*n+3]=2*n+2; Tree.rs[2*n+3]=n+2; 
	m=2*n+3; n=n+2; 
	dep[m]=1; Tree.dfs1(m); 
	S1.build(S1.rt, 1, m); S2.build(S2.rt, 1, m); 
	Tree.dfs2(m, m); 
	for(k=1; k<=20; ++k)
		for(i=1; i<=m; ++i) {
			f[i][k]=f[f[i][k-1]][k-1]; 
		}
	while(q--) {
		op=read(); 
		if(op==1) {
			x=read()+1; y=read()+1; d=read(); 
			lxy=lca(x-1, y+1); 
			Tree.add(S1, x-1, Tree.ls[lxy], d); 
			Tree.add(S2, y+1, Tree.rs[lxy], d); 
		}
		else {
			x=read()+1; y=read()+1; 
			lxy=lca(x-1, y+1); ans=0; 
			ans+=Tree.que(S1, x-1, Tree.ls[lxy]); 
			ans+=Tree.que(S2, y+1, Tree.rs[lxy]); 
			printf("%lld\n", ans); 
		}
	}
	return 0;
}



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1010158.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为云Stack的学习(六)

七、华为云Stack计算服务介绍 1.计算服务整体介绍 2.弹性云服务器ECS ECS&#xff08;Elastic Cloud Server&#xff09;&#xff0c;即弹性云服务器&#xff0c;是由vCPU、内存、磁盘等组成的&#xff0c;获取方便、弹性可扩展、按需使用的、虚拟的计算服务器。 ECS只需要花…

【深度学习】 Python 和 NumPy 系列教程(十四):Matplotlib详解:1、2d绘图(下):箱线图、热力图、面积图、等高线图、极坐标图

目录 一、前言 二、实验环境 三、Matplotlib详解 1、2d绘图类型 0. 设置中文字体 1-5. 折线图、散点图、柱状图、直方图、饼图 6. 箱线图&#xff08;Box Plot&#xff09; 7. 热力图&#xff08;Heatmap&#xff09; 8. 面积图&#xff08;Area Plot&#xff09; 9. 等…

Zabbix“专家坐诊”第203期问答汇总

问题一 Q&#xff1a;用的模板&#xff0c;没用创建动作&#xff0c;但是触发器触发了我钉钉直接被通知了&#xff0c;怎么取消模板自带的动作&#xff1f; A&#xff1a;没有动作是不会触发事件告警的 &#xff0c;确定是从这个平台推出的钉钉消息&#xff1f;或者看下zabbix…

【操作系统】进程的通信IPC

进程通信是指进程之间的信息交换。 低级通信方式&#xff1a;PV操作 高级通信方式&#xff1a;1.共享存储2.消息传递3.管道通信 共享存储 低级数据结构共享&#xff0c;高级存储区共享。 对共享空间进行读写操作时&#xff0c;需要用到互斥工具。 消息传递 利用发送消息和…

Leetcode算法入门与数组丨3. 数组基础

文章目录 前言1 数组简介2 数组的基本操作2.1 访问元素2.2 查找元素2.3 插入元素2.4 改变元素2.5 删除元素 3 总结task03task04 前言 Datawhale组队学习丨9月Leetcode算法入门与数组丨打卡笔记 这篇博客是一个 入门型 的文章&#xff0c;主要是自己学习的一个记录。 内容会参…

Matlab图像处理-三原色

三原色 根据详细的实验结果&#xff0c;人眼中负责颜色感知的细胞中约有65%对红光敏感&#xff0c;33%对绿光敏感&#xff0c;只有2%对蓝光敏感。正是人眼的这些吸收特性决定了所看到的彩色是一般所谓的原色红&#xff08;R&#xff09;、绿&#xff08;G&#xff09;和蓝&…

十四、流式编程(1)

本章概要 流支持流创建 随机数流int 类型的范围generate()iterate()流的建造者模式Arrays正则表达式 集合优化了对象的存储&#xff0c;而流&#xff08;Streams&#xff09;则是关于一组组对象的处理。 流&#xff08;Streams&#xff09;是与任何特定存储机制无关的元素序列…

【2023】windows下安装libevent

Windows安装libevent 1.安装Visual Studio2.安装openssl第一种安装方式&#xff1a;[简便安装](https://slproweb.com/products/Win32OpenSSL.html)第二种&#xff1a;自己编译openssl 3.libevent下载libevent修改文件1.下边三个文件加入宏定义 #define _WIN32_WINNT 0x05002.修…

基于卷积神经网络的手写字体识别(详细笔记)

主要参考博客&#xff1a; 1、 基于卷积神经网络的手写数字识别&#xff08;附数据集完整代码操作说明&#xff09; 2、用PyTorch实现MNIST手写数字识别&#xff08;最新&#xff0c;非常详细&#xff09; 基于卷积神经网络的手写字体识别——目录 1 前言1.1 实现效果1.2 学习背…

国产洗碗机打响超越战

“征服世界的将是这样一些人&#xff1a;开始的时候&#xff0c;他们试图找到梦想中的乐园。最终&#xff0c;当他们无法找到时&#xff0c;就亲自创造了它。”诺贝尔文学奖获得者萧伯纳的这句话&#xff0c;适用于许多中国行业和企业&#xff0c;洗碗机就是其中之一。 对热爱…

十进制小数转换为单双精度浮点数方法

1 将十进制小数转换为单精度浮点数的方法如下&#xff1a; 2. 将十进制小数转换为双精度浮点数的方法如下&#xff1a; 和单精度浮点值转换一样

前端Layui框架介绍

当涉及到前端UI框架时&#xff0c;Layui&#xff08;简称layui&#xff09;是一个备受欢迎的框架之一。在这篇博客中&#xff0c;我们将深入了解layui&#xff0c;包括其市场占有率、开发语言、使用场景、框架特点以及一些使用案例。 1. 市场占有率 Layui 是一款流行的前端UI框…

(纯干货建议收藏)大型字符串模拟-超强超全函数技巧总结

这篇文章将会总结一些处理字符串、进制转换等等的常见的、非常有用的技巧和函数。后续会随时更新本文章&#xff0c;希望大家收藏、留言&#xff0c;一起学习进步&#xff01; 对于特别简单的函数&#xff0c;就不写函数的详细原型啦&#xff01; 具体包含四部分&#xff0c;…

Xilinx FPGA未使用管脚上下拉状态配置(ISE和Vivado环境)

文章目录 ISE开发环境Vivado开发环境方式1&#xff1a;XDC文件约束方式2&#xff1a;生成选项配置 ISE开发环境 ISE开发环境&#xff0c;可在如下Bit流文件生成选项中配置。 右键点击Generate Programming File&#xff0c;选择Process Properties&#xff0c; 在弹出的窗口选…

《程序员职场工具库》如何优化你的工作 —— PDCA 循环

PDCA 循环简介 PDCA 循环是一种以持续改进为核心思想的管理方法&#xff0c;在全球各个领域得到广泛的应用。它还有好几个别称&#xff0c;叫“质量环”&#xff0c;也叫“戴明环”&#xff0c;也有叫“持续改进螺旋”。 PDCA 循环由四个步骤组成&#xff1a; 计划&#xff…

基于SSM+Vue的中国咖啡文化宣传网站

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用vUE技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

vector模拟实现——关于模拟中的易错点

前言 vector 本质上类似数组&#xff0c;也可以理解为一种泛型的 string。string 只能存储 char 类型&#xff0c;但是 vector 支持各种内置类型和自定义类型。本次将围绕模拟实现 vector 中遇到的问题进行分析。 文章目录 前言一、确定思路二、实现过程2.1 查阅文档2.2 验证…

4-3 nn.functional和nn.Module

一&#xff0c;nn.functional 和 nn.Module 前面我们介绍了Pytorch的张量的结构操作和数学运算中的一些常用API。利用这些张量的API我们可以构建出神经网络相关的组件(如激活函数&#xff0c;模型层&#xff0c;损失函数)。 其实&#xff1a;Pytorch和神经网络相关的功能组件大…

中小企业数字化转型难?为什么不试试“企业级”无代码平台

首先&#xff0c;让我们思考一下&#xff0c;中小企业为什么要进行数字化转型&#xff1f;随着全球经济的数字化趋势日益明显&#xff0c;中小企业作为经济的重要组成部分&#xff0c;其数字化转型已成为推动经济高质量发展的关键。数字技术可以帮助中小企业提高生产效率、降低…

ctfshow-web-红包题 辟邪剑谱

0x00 前言 CTF 加解密合集CTF Web合集网络安全知识库溯源相关 文中工具皆可关注 皓月当空w 公众号 发送关键字 工具 获取 0x01 题目 0x02 Write Up 这道题主要是考察mysql查询绕过的问题。 首先访问后看到是一个登录页面&#xff0c;测试注册等无果 扫描目录&#xff0c;发…