CF 1843F2 - Omsk Metro (hard version)

2023-11-05

CF 1843F2 - Omsk Metro (hard version)

题目描述

给定 n n n 个节点的有根树,根节点为 1 1 1,每个节点上有权值 0 0 0 1 1 1

q q q 次询问,每次询问 u u u v v v 路径上的最大子段和。

数据范围

1 ≤ n ≤ 2 ⋅ 1 0 5 , 1 ≤ q ≤ 2 ⋅ 1 0 5 1 \leq n \leq 2 \cdot 10^5, 1 \leq q \leq 2 \cdot 10^5 1n2105,1q2105


题解报告

假设树的形状是一条链,即每次询问数组上一段连续区间内的最大子段和,

可以通过维护前缀和,计算询问区间内最大前缀和与最小前缀和,两者相减即为该询问区间的最大字段和。

对于树形结构,可以采用相同的思想,利用前缀和的差来计算答案。

考虑 u u u v v v 的祖先(或反过来)的情况,

答案即为路径上最大前缀和最小前缀的差;

假如 u u u v v v 之间不存在祖先关系,令 l c a lca lca 为两点的最近公共祖先,

则最大子段要么全部位于 l c a lca lca u u u 的路径中,要么全部位于 l c a lca lca v v v 的路径中,要么被 l c a lca lca 节点分成两部分;

对于前两种情况,和上述讨论是相同的;

对于第三种情况,答案即为 l c a lca lca u u u 之间的最大前缀加上 l c a lca lca v v v 之间的最大前缀减去 l c a lca lca 的前缀的两倍再加上 l c a lca lca 的权值。

归根到底都是求路径上的最大值和最小值,可以用树剖 + + + 线段树维护;

不过有更简单的方法,倍增。

n o d e [ i ] [ j ] node[i][j] node[i][j],表示第 i i i 个节点向上 2 j 2^j 2j 步之间所有节点(不包括终点)的前缀和的最大值和最小值,

更新方式很传统, n o d e [ i ] [ j ] = m a x / m i n ( n o d e [ i ] [ j − 1 ] , n o d e [ f a [ i ] [ j − 1 ] ] [ j − 1 ] ) node[i][j] = max/min (node[i][j - 1], node[fa[i][j - 1]][j - 1]) node[i][j]=max/min(node[i][j1],node[fa[i][j1]][j1])

AC代码:

#include <bits/stdc++.h>
#define ll long long
#define int ll
using namespace std;
const int N = 2e5 + 5;
const int M = 20;

struct Node {
	int mx_suf, mx_seg;
	int mn_suf, mn_seg;
	
	void Merge (Node &a) {
		this -> mx_seg = max ({this -> mx_seg, a.mx_seg, this -> mx_suf - a.mn_suf});
		this -> mn_seg = min ({this -> mn_seg, a.mn_seg, this -> mn_suf - a.mx_suf});
		this -> mx_suf = max (this -> mx_suf, a.mx_suf);
		this -> mn_suf = min (this -> mn_suf, a.mn_suf);
	}
};

int Get_lca (int u, int v, vector <vector <int> > &fa, vector <int> &dep) {
	if (dep[u] < dep[v]) swap (u, v);
	for (int i = M - 1; i >= 0; --i) {
		if (dep[fa[u][i]] > dep[v]) u = fa[u][i];
	}
	if (dep[u] > dep[v]) u = fa[u][0];
	for (int i = M - 1; i >= 0; --i) {
		if (fa[u][i] != fa[v][i]) {
			u = fa[u][i];
			v = fa[v][i];
		}
	}
	if (u != v) return fa[u][0];
	else return u;
}

Node Get_ans (int u, int lca, vector <vector <Node> > &node, 
vector <vector <int> > &fa, vector <int> &dep) {
	Node ans = {-1, -1, -1, -1};
	for (int i = M - 1; i >= 0; --i) {
		if (dep[fa[u][i]] >= dep[lca]) {
			if (ans.mx_seg == -1) ans = node[u][i];
			else ans.Merge (node[u][i]);
			u = fa[u][i];
		}
	}
	if (ans.mx_seg == -1) ans = node[u][0];
	else ans.Merge (node[u][0]);
	return ans;
}

int t, n;

void init () {}

void charming () {
	init ();
	cin >> n;
	vector <vector <int> > fa (n + 5, vector <int> (M));
	vector <vector <Node> > node (n + 5, vector <Node> (M));
	node[1][0] = (Node) {1, 1, 1, 0};
	vector <int> suf (n + 5), dep (n + 5), val (n + 5);
	suf[1] = dep[1] = val[1] = 1;
	for (int i = 1; i < M; ++i) node[1][i] = node[1][i - 1];
	char op;
	for (int i = 1, u, v, x, k, cnt = 1, mn, mx, lca; i <= n; ++i) {
		cin >> op;
		if (op == '+') {
			++cnt, cin >> v >> x;
			fa[cnt][0] = v;
			for (int i = 1; i < M; ++i) fa[cnt][i] = fa[fa[cnt][i - 1]][i - 1];
			suf[cnt] = suf[v] + x, dep[cnt] = dep[v] + 1, val[cnt] = x;
			node[cnt][0] = (Node) {suf[cnt], max (0ll, x), suf[cnt], min (0ll, x)};
			for (int i = 1; i < M; ++i) {
				node[cnt][i] = node[cnt][i - 1];
				node[cnt][i].Merge (node[fa[cnt][i - 1]][i - 1]);
			}
		} else {
			cin >> u >> v >> k;
			mn = mx = 0;
			lca = Get_lca (u, v, fa, dep);
			Node ans_u = Get_ans (u, lca, node, fa, dep);
			Node ans_v = Get_ans (v, lca, node, fa, dep);
			mn = min ({mn, ans_u.mn_seg, ans_v.mn_seg, ans_u.mn_suf + ans_v.mn_suf - suf[lca] * 2 + val[lca]});
			mx = max ({mx, ans_u.mx_seg, ans_v.mx_seg, ans_u.mx_suf + ans_v.mx_suf - suf[lca] * 2 + val[lca]});
			if (k >= mn && k <= mx) cout << "YES" << endl;
			else cout << "NO" << endl;
		}
	}
}

signed main () {
	cin >> t;
	while (t--) charming ();
	return 0;
}

后记

想了半天都没想出来怎么写的,看了别人的代码才发现这么简单…主要是刚开始方向都没对,到后面都想到了线段树合并那里了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CF 1843F2 - Omsk Metro (hard version) 的相关文章

  • CLR 2.0 与 4.0 性能比较?

    如果在 CLR 4 0 下运行 为 CLR 2 0 编译的 NET 程序会运行得更快吗 应用程序配置
  • 使用 C# 登录《我的世界》

    我正在尝试为自己和一些朋友创建一个简单的自定义 Minecraft 启动器 我不需要启动 Minecraft 的代码 只需要登录的实际代码行 例如 据我所知 您过去可以使用 string netResponse httpGET https
  • 代码 GetAsyncKeyState(VK_SHIFT) & 0x8000 中的这些数字是什么?它们是必不可少的吗?

    我试图在按下按键的简单动作中找到这些数字及其含义的任何逻辑解释 GetAsyncKeyState VK SHIFT 0x8000 可以使用哪些其他值来代替0x8000它们与按键有什么关系 GetAsyncKeyState 根据文档返回 如果
  • GetType() 在 Type 实例上返回什么?

    我在一些调试过程中遇到了这段代码 private bool HasBaseType Type type out Type baseType Type originalType type GetType baseType GetBaseTyp
  • 为什么pow函数比简单运算慢?

    从我的一个朋友那里 我听说 pow 函数比简单地将底数乘以它的指数的等价函数要慢 例如 据他介绍 include
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • IdentityServer 4 对它的工作原理感到困惑

    我阅读和观看了很多有关 Identity Server 4 的内容 但我仍然对它有点困惑 因为似乎有很多移动部件 我现在明白这是一个单独的项目 它处理用户身份验证 我仍然不明白的是用户如何注册它 谁存储用户名 密码 我打算进行此设置 Rea
  • 查找进程的完整路径

    我已经编写了 C 控制台应用程序 当我启动应用程序时 不使用cmd 我可以看到它列在任务管理器的进程列表中 现在我需要编写另一个应用程序 在其中我需要查找以前的应用程序是否正在运行 我知道应用程序名称和路径 所以我已将管理对象搜索器查询写入
  • 如何使用 Castle Windsor 将对象注入到 WCF IErrorHandler 实现中?

    我正在使用 WCF 开发一组服务 该应用程序正在使用 Castle Windsor 进行依赖注入 我添加了一个IErrorHandler通过属性添加到服务的实现 到目前为止一切正常 这IErrorHandler对象 一个名为FaultHan
  • unordered_map 中字符串的 C++ 哈希函数

    看起来 C 标准库中没有字符串的哈希函数 这是真的 在任何 c 编译器上使用字符串作为 unordered map 中的键的工作示例是什么 C STL提供模板专业化 http en cppreference com w cpp string
  • 对 std::vector 进行排序但忽略某个数字

    我有一个std vector
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 告诉 Nancy 将枚举序列化为字符串

    Nancy 默认情况下在生成 JSON 响应时将枚举序列化为整数 我需要将枚举序列化为字符串 有一种方法可以通过创建来自定义 Nancy 的 JSON 序列化JavaScript 原始转换器 https github com NancyFx
  • C# 存档中的文件列表

    我正在创建一个 FileFinder 类 您可以在其中进行如下搜索 var fileFinder new FileFinder new string C MyFolder1 C MyFolder2 new string
  • 如何在 C 中安全地声明 16 位字符串文字?

    我知道已经有一个标准方法 前缀为L wchar t test literal L Test 问题是wchar t不保证是16位 但是对于我的项目 我需要16位wchar t 我还想避免通过的要求 fshort wchar 那么 C 不是 C
  • 等待 IAsyncResult 函数直至完成

    我需要创建等待 IAsyncResult 方法完成的机制 我怎样才能做到这一点 IAsyncResult result contactGroupServices BeginDeleteContact contactToRemove Uri
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • GCC 的“-Wl,option”和“-Xlinker option”语法之间有区别吗?

    我一直在查看一些配置文件 并且看到它们都被使用 尽管在不同的体系结构上 如果您在 Linux 机器上使用 GCC 将选项传递给链接器的两种语法之间有区别吗 据我所知 阅读 GCC 手册时 他们的解释几乎相同 From man gcc Xli
  • 灵气序列解析问题

    我在使用 Spirit Qi 2 4 编写解析器时遇到一些问题 我有一系列键值对以以下格式解析

随机推荐

  • Android购物车效果实现(RecyclerView悬浮头部实现)

    刚开始看购物车效果觉得挺复杂 但是把这个功能拆开来一步一步实现会发现并不难 其实就涉及到 ItemDecoration的绘制 recyclerview的滑动监听 贝塞尔曲线和属性动画相关内容 剩下的就是RecyclerView滑动和点击时左
  • Xshell6和Xftp提示“要继续使用此程序,您必须应用最新的更新或使用新版本“

    Xshell6和Xftp提示 要继续使用此程序 您必须应用最新的更新或使用新版本 使用二进制编辑器修改Xshell和Xftp的nslicense dll文件 如sublime Txt编辑器等 1 分别进入Xshell和Xftp的安装路径下
  • torch.autograd.grad求二阶导数

    1 用法介绍 pytorch中torch autograd grad函数主要用于计算并返回输出相对于输入的梯度总和 具体的参数作用如下所示 torch tril input diagonal 0 out None longrightarro
  • C语言:求斐波那契数列前n项的和

    include
  • 经典卷积神经网络——resnet

    resnet 前言 一 resnet 二 resnet网络结构 三 resnet18 1 导包 2 残差模块 2 通道数翻倍残差模块 3 rensnet18模块 4 数据测试 5 损失函数 优化器 6 加载数据集 数据增强 7 训练数据 8
  • linux安装python3以及pip过程,遇到的错误处理

    需要自己搭建环境 没想到的是基本的安装python3过程过程就踩了很多坑 希望对别人有帮助 参考 https www centoschina cn course config 11027 html 1 下载相应python3 7解释器htt
  • Unity—3D数学基础

    今天用了小半天时间初步了解3D数学基础 明天开始进入unity游戏脚本编写 每日一句 人间骄阳正好 风过林梢 彼时我们正当年少 目录 3D坐标系 全局 世界 坐标系 局部 模型 物体 坐标系 相机坐标系 屏幕坐标系 向量 向量的运算 Vec
  • div滚动到顶部或者底部触发分页查询方法

    如聊天界面 滚动到顶部触发分页 div标签里添加滚动事件 scroll passive getScrollUser event 方法 getScroll event if event target scrollTop 0 this chat
  • 6.824分布式

    MapReduce 例子加深理解 你的工作是实现一个分布式的MapReduce 包括两个程序 master 和 worker 只有一个master进程 以及 一个或多个worker进程并行执行 在真实的系统中 工作人员将在许多不同的机器上运
  • 【安全工具】Web漏洞扫描十大工具

    Web漏洞扫描十大工具 Acunetix Web Vulnerability Scanner 简称AwVS AwVS是一款知名的Web网络漏洞扫描工具 它通过网络爬虫测试你的网站安全 检测流行安全漏洞 a 自动的客户端脚本分析器 允许对Aj
  • 关于springBoot如何配置双数据源

    前言 本文采用springBoot 配置类的方式简单配置Mysql PostgreSql双数据源 1 首先导入需要的pom依赖
  • 配置测试

    1 配置测试 configuration testing 配置测试是指使用各种硬件来测试软件运行的过程 2 基于Windows的PC机包括 个人计算机 部件 系统主板 内部板卡和其他内部设备 外设 接口 可选项和内存 设备驱动程序 3 配置
  • 轻松理解转置卷积(transposed convolution)或反卷积(deconvolution)

    本译文很大程度上保留了原文原貌 并添加了细节便于理解 各种指代 在CNN中 转置卷积是一种上采样 up sampling 的常见方法 如果你不清楚转置卷积是怎么操作的 那么就来读读这篇文章吧 本文的notebook代码在Github 上采样
  • Redis——数据结构介绍

    Redis是一个key value的数据库 key一般是String类型 不过value的类型是多样的 String hello word Hash name Jack age 21 List A gt B gt C gt D Set A
  • SaltStack 自动化运维详解

    一 自动化运维工具对比 使用所需软件配置单个服务器是一项相当简单的任务 但是 如果许多服务器需要安装相同或相似的软件和配置 则该过程将需要大量的工时才能完成 这会耗尽您本已紧张的资源 如果没有某种形式的自动化 这项任务几乎无法完成 考虑到这
  • 关于SpringMVC返回date的格式问题

    Spring 项目中 java的util date和java time类型的日期 返回到前端的时候 默认的序列化方式显示的是标准格式 为了能够正确的显示想要的时间 可以使用jackson指定时间的格式 访问我的个人网站获取更多文章 数据库的
  • 汽车的操作系统AUTOSAR

    汽车软件开发autosar 01汽车相关知识 汽车发展三大趋势 电动化 智能化 网联化 1 电动化 底层支撑 网联化的驱动力 2 智能化 人工智能借助软硬融合带来功能升级 体验升级 安全升级 3 网联化 5G的应用场景 让汽车与人 车 物的
  • golang实现p2p之UDP打洞

    当今互联网到处存在着一些中间件 MIddleBoxes 如NAT和防火墙 导致两个 不在同一内网 中的客户端无法直接通信 这些问题即便是到了IPV6时代也会存在 因为即使不需要NAT 但还有其他中间件如防火墙阻挡了链接的建立 目前部署的中间
  • spring boot毕业生跟踪调查管理系统 毕业设计源码论文+答辩PPT

    答辩PPT 论文 springboot毕业生跟踪调查管理系统 摘 要 信息化社会内需要与之针对性的信息获取途径 但是途径的扩展基本上为人们所努力的方向 由于站在的角度存在偏差 人们经常能够获得不同类型信息 这也是技术最为难以攻克的课题 针对
  • CF 1843F2 - Omsk Metro (hard version)

    CF 1843F2 Omsk Metro hard version 题目描述 给定 n n n 个节点的有根树 根节点为 1 1 1 每个节点上有权值 0