dfs序+线段树,CF 838B - Diverging Directions

news2024/12/28 18:07:10

目录

一、题目

1、题目描述

2、输入输出

2.1输入

2.2输出

3、原题链接

二、解题报告

1、思路分析

2、复杂度

3、代码详解


一、题目

1、题目描述

2、输入输出

2.1输入

2.2输出

3、原题链接

838B - Diverging Directions


二、解题报告

1、思路分析

注意这是一棵有向树

添加了“回跳边”后

对于任意查询<u, v>

如果 v 在 u 子树内,显然从u直接走到v是最短的,答案为 d[v] - d[u]

否则,路径应该是 从 u 走到 子树内某节点x,从x走"回跳边"到根,再从根走到v

上述路径长度为:d[x] - d[u] + up[x] + d[v]

即,答案为 min{up[x] + d[x]} + d[v] - d[u]

发现我们似乎只需维护 min { up[x] + d[x] }

那么我们发现操作树边,相当于是修改一棵子树的 {up[x] + d[x]}

操作回跳边,则是单点修改up[x] + d[x]

所以,我们只需用线段树维护 dfs序列上的 {up[x] + d[x]}即可

2、复杂度

时间复杂度: O(qlogn)空间复杂度:O(nlogn)

3、代码详解

 ​
#include <bits/stdc++.h>

// #define DEBUG

using i64 = long long;
using u32 = unsigned int;
using u64 = unsigned long long;

constexpr int inf32 = 1E9 + 7;
constexpr i64 inf64 = 1E18 + 7;
constexpr int P = 1E9 + 7;

template <class Info, class Tag>
struct LazySegmentTree {
    const int n;
    std::vector<Info> info;
    std::vector<Tag> tag;
    LazySegmentTree(int _n) : n(_n), info(2 << (32 - __builtin_clz(n))), tag(2 << (32 - __builtin_clz(n))){}
    
    void pull(int p) {
        info[p] = info[p << 1] + info[p << 1 | 1];
    }

    void apply(int p, const Tag &t) {
        info[p].apply(t);
        tag[p].apply(t);
    }

    void push(int p) {
        apply(p << 1, tag[p]);
        apply(p << 1 | 1, tag[p]);
        tag[p] = Tag();
    }

    template<class T>
    LazySegmentTree(std::vector<T>& _init): LazySegmentTree(_init.size()) {
        auto build = [&](auto&& self, int p, int l, int r) {
            if (l == r) {
                info[p] = { _init[l] };
                return;
            }
            int mid = l + r >> 1;
            self(self, p << 1, l, mid), self(self, p << 1 | 1, mid + 1, r);
            pull(p);
        };
        build(build, 1, 0, n - 1);
    }

    Info rangeQuery(int p, int l, int r, int x, int y) {
        if (l > y || r < x) return Info();
        if (x <= l && r <= y) 
            return info[p];
        push(p);
        int mid = l + r >> 1;
        return rangeQuery(p << 1, l, mid, x, y) + rangeQuery(p << 1 | 1, mid + 1, r, x, y);
    }

    Info rangeQuery(int l, int r) {
        return rangeQuery(1, 0, n - 1, l, r);
    }

    void rangeApply(int p, int l, int r, int x, int y, const Tag &v){
        if (l > y || r < x) return;
        if (x <= l && r <= y) { 
            apply(p, v);
            return;
        }

        int mid = l + r >> 1;
        push(p);
        rangeApply(p << 1, l, mid, x, y, v);
        rangeApply(p << 1 | 1, mid + 1, r, x, y, v);
        pull(p);
    }

    void rangeApply(int l, int r, const Tag &v) {
        rangeApply(1, 0, n - 1, l, r, v);
    }
};

struct Tag {
    i64 add = 0;

    void apply(const Tag& t) {
        add += t.add;
    }
};

struct Info {
    i64 mi = inf64;
    void apply(const Tag &t) {
        mi += t.add;
    }
};

Info operator + (const Info &x, const Info &y) {
    return { std::min(x.mi, y.mi) };
}

struct Edge{
	int v, w;
};

void solve(){
	int n, q;
	std::cin >> n >> q;

	std::vector<Edge> e;
	std::vector<std::vector<int>> g(n);
	std::vector<i64> up(n);

	for (int i = 0, u, v, w, ed = 2 * n - 2; i < ed; ++ i) {
		std::cin >> u >> v >> w;
		-- u, -- v;
		if (v) {
			e.emplace_back(v, w);
			g[u].push_back(i);
		}
		else {
			e.emplace_back(u, w);
			up[u] = w;
		}
	}


	std::vector<int> dfn(n), sz(n);
	std::vector<i64> d(n);
	int cur = 0;
	
	auto dfs = [&](auto &&self, int u) -> void {
		dfn[u] = cur ++, sz[u] = 1;
		for (int i : g[u]) {
			auto [v, w] = e[i];
			d[v] = d[u] + w;
			self(self, v);
			sz[u] += sz[v];
		}
	};

	dfs(dfs, 0);

	std::vector<i64> val(n, -1);
	for (int i = 0; i < n; ++ i) {
		assert(val[dfn[i]] == -1);
		val[dfn[i]] = up[i] + d[i];
	}

	LazySegmentTree<Info, Tag> sgt(val);

	auto get = [&](int u) -> i64 {
		return sgt.rangeQuery(dfn[u], dfn[u]).mi;
	};

	for (int i = 0, op, x, y; i < q; ++ i) {
		std::cin >> op >> x >> y;
		if (op == 1) {
			if (x >= n) {
				int v = e[x - 1].v;
				sgt.rangeApply(dfn[v], dfn[v], Tag{y - up[v]});
				up[v] = y;
			}
			else {
				int v = e[x - 1].v;
				sgt.rangeApply(dfn[v], dfn[v] + sz[v] - 1, Tag{y - e[x - 1].w});
				e[x - 1].w = y;
			}
		}
		else {
			-- x, -- y;
			if (dfn[x] <= dfn[y] && dfn[y] <= dfn[x] + sz[x] - 1) {
				std::cout << get(y) - up[y] - get(x) + up[x] << '\n';
				continue;
			}
			std::cout << sgt.rangeQuery(dfn[x], dfn[x] + sz[x] - 1).mi + get(y) - up[y] - get(x) + up[x] << '\n';
		}
	}
}

auto FIO = []{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);
	return 0;
}();

int main() {
	#ifdef DEBUG
		freopen("in.txt", 'r', stdin);
		freopen("out.txt", 'w', stdout);
	#endif
	int t = 1;
	// std::cin >> t;
	while(t --)
		solve();
	return 0;
}

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

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

相关文章

正点原子STM32F103+ESP8266+DS18B20+DHT11连接阿里云

文章目录 MQTT协议1. 基础知识2. 报文形式3. 连接报文4. 心跳报文5. 订阅报文5.1. 订阅主题报文SUBSCRIBE5.2. 订阅确认SUBACK5.3. 取消订阅UNSUBSCRIBE5.4. 取消订阅确认UNSUBACK 6. 发布报文6.1. 发布消息PUBLISH6.2. 发布确认PUBACK 7. 阿里云账号创建8. 网络调试助手接入阿…

机器人助力上下料搬运,加速仓库转运自动化

近年来&#xff0c;国内制造业领域掀起了一股智能化改造的浪潮&#xff0c;众多工厂纷纷采纳富唯智能提供的先进物流解决方案&#xff0c;这一举措显著优化了生产流程&#xff0c;实现了生产效率的飞跃式增长。得益于这些成功案例&#xff0c;某信息技术服务企业在工厂智能物流…

如何打造高校实验室教学管理系统?Java SpringBoot助力,MySQL存储优化,2025届必备设计指南

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

每日一题——第八十一题

打印如下图案: #include<stdio.h> int main() {int i, j;char ch A;for (i 1; i < 5; i, ch){for (j 0; j < 5 - i; j){printf(" ");//控制空格输出}for (j 1; j < 2 * i; j)//条件j < 2 * i{printf("%c", ch);//控制字符输出}prin…

❤《实战纪录片 1 》原生开发小程序中遇到的问题和解决方案

《实战纪录片 1 》原生开发小程序中遇到的问题和解决方案 文章目录 《实战纪录片 1 》原生开发小程序中遇到的问题和解决方案1、问题一&#xff1a;原生开发中 request请求中返回 的数据无法 使用this传递给 data{}中怎么办&#xff1f;2、刚登录后如何将token信息保存&#xf…

[网鼎杯 2020 青龙组]bang-快坚持不下去的第五天

ps:安卓的解壳&#xff0c;也就是frida-dexdump一把嗦&#xff0c;其他wp上说用真机成功的几率大一些&#xff0c;我就用的模拟器 详细的看这一篇博客&#xff1a; 安卓模拟器Frida环境搭建 &#xff08;mumuadbfrida&#xff09; 在python中安装frida时多一步 pip install…

【Dash】feffery_antd_componenet 中的 AntdSpace

一、feffery_antd_componenet 中的 AntdSpace feffery_antd_components&#xff08;简称fac&#xff09;中的AntdSpace组件是一个基于Ant Design的Dash第三方组件&#xff0c;它用于在水平或垂直方向上放置多个元素&#xff0c;并提供元素之间的间距。以下是AntdSpace组件的一…

一文说清什么是AI原生(AI Native)应用以及特点

引言&#xff1a;智能新纪元 如今&#xff0c;走在街头&#xff0c;哪儿不被智能科技包围&#xff1f;智能音箱、自动驾驶汽车、聊天机器人......这些都在用不同的方式提升我们的生活体验。然而&#xff0c;究竟什么才能称得上“AI原生应用”呢&#xff1f; 什么是AI原生&…

C++:STL简介

✨ Blog’s 主页: 白乐天_&#xff3e;&#xff56;&#xff3e; &#x1f308; 个人Motto&#xff1a;他强任他强&#xff0c;清风拂山岗&#xff01; &#x1f4ab; 欢迎来到我的学习笔记&#xff01; 一、STL引入 STL&#xff08;Standard template libaray-标准模板库…

最新厦门新能安社招入职Verify测评笔试攻略敬请查收SHL

作为全球知名锂电池供应商——ATL与CATL的合资公司&#xff0c;新能安专注高端锂电池的研究与创新&#xff0c;聚焦储能系统、微型车、智能产品驱动电池等三大领域的研发、生产、销售与服务。 a.测评内容包含演绎推理数字推理两部分&#xff0c;大约用时40分钟左右; b.正式测评…

node.js实现阿里云短信发送

效果图 实现 一、准备工作 1、官网直达网址&#xff1a; 阿里云 - 短信服务 2、按照首页提示依次完成相应资质认证和短信模板审核&#xff1b; 3、获取你的accessKeySecret和accessKeyId&#xff1b; 方法如下&#xff1a; 获取AccessKey-阿里云帮助中心 4、获取SignNa…

测试你们认为最好的AI工具,是不是好用得自己试试!

大家好&#xff0c;我是凡人&#xff0c;在 OpenAI 春季发布会后&#xff0c; GPT-4o 一时风光无量&#xff0c;一个同事不信邪&#xff0c;非要用 GPT-4o 版本对 OpenAI 官网上的例子尝试生成&#xff0c;本来还是嘲笑他的心态&#xff0c;但他还真的发现了点有意思的事情。 …

多线程篇(阻塞队列- BlockingQueue)(持续更新迭代)

目录 一、了解什么是阻塞队列之前&#xff0c;需要先知道队列 1. Queue&#xff08;接口&#xff09; 二、阻塞队列 1. 前言 2. 什么是阻塞队列 3. Java里面常见的阻塞队列 三、BlockingQueue&#xff08;接口&#xff09; 1. 前言 2. 简介 3. 特性 3.1. 队列类型 …

实时地图+瞬移,黑神话地图工具来了

工具下载: https://pan.quark.cn/s/12b9cef46bf0 瞬移功能使用说明&#xff1a; 1、必须在一修大师客户端: 使用猫修APP扫码登陆后使用&#xff1b; 2、打开《黑神话》游戏&#xff1b; 3、点击修改器页面右上角“开始使用”按钮&#xff1b; 4、点击你想要瞬移的点位图标…

使用Azure Devops Pipeline将Docker应用部署到你的Raspberry Pi上

文章目录 1. 添加树莓派到 Agent Pool1.1 添加pool1.2 添加agent 2. 将树莓派添加到 Deployment Pool2.1 添加pool2.2 添加target 3. 添加编译流水线3.1 添加编译命令3.2 配置触发器 4. 添加发布流水线4.1 添加命令行4.2 配置artifact和触发器 5. 完成 1. 添加树莓派到 Agent P…

spring项目使用邮箱验证码校验

本项目采用免费QQ邮箱验证码方式进行登录安全的校验。 前期工作 申请邮箱安全授权码 打开QQ邮箱官网点击设置 进入设置页面后点击账户按钮 进入账户后一直往下拉页面找到POP3服务栏&#xff0c;然后点击管理服务&#xff08;如果没有开启服务需要先开启服务&#xff0c;按照…

vivado 时钟交互报告

步骤6&#xff1a;时钟交互报告 在创建约束之后或期间&#xff0c;必须验证约束是否完整且安全。 Vivado Design Suite默认情况下将所有时钟一起计时&#xff0c;除非您通过定义另有指定 时钟组或其他定时异常。set_clock_groups命令指定 异步或独占时钟域&#xff0c;并禁用它…

GIT | git提交注释自动添加信息头

GIT | git提交注释自动添加信息头 时间&#xff1a;2024年9月6日10:20:11 文章目录 GIT | git提交注释自动添加信息头1.操作2.commit-msg文件 1.操作 2.commit-msg文件 #!/bin/sh # # An example hook script to check the commit log message. # Called by "git commit&q…

OXC:光交叉连接(optical cross-connect)-介绍

1. 引用 https://zhuanlan.zhihu.com/p/259797386 实现对光网络的监控和光路切换 - MEMS 光开关-CSDN博客 MEMS光学器件— MEMS OXC&#xff08;光交叉互连开关&#xff09;_基于1n端口光开关构建的oxc-CSDN博客 OXC和OADM_oadm oxc-CSDN博客 光的世界第二弹&#xff1a;O…

2024全国大学生数学建模竞赛B题完整论文讲解

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了2024 年全国大学生数学建模竞赛B 题 生产过程中的决策问题 完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。 …