[SDOI2017]树点涂色

2023-10-27

洛谷 [SDOI2017]树点涂色

题目描述

Bob 有一棵 n n n 个点的有根树,其中 1 1 1 号点是根节点。Bob 在每个点上涂了颜色,并且每个点上的颜色不同。

定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。

Bob可能会进行这几种操作:

  • 1 x 表示把点 x x x 到根节点的路径上所有的点染上一种没有用过的新颜色。

  • 2 x y x x x y y y 的路径的权值。

  • 3 x 在以 x x x 为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。

Bob一共会进行 m m m 次操作

数据范围

$1\leq n \leq 10^5,1\leq m \leq 10^5 $


题解报告

我们定义每个点的权值 v a l [ i ] val[i] val[i] 为, i i i 点到根节点路径的权值。

由操作 1 1 1,我们可以以 LCT 的 A c c e s s Access Access 操作为模型来实现操作1,具体来说就是, v a l [ i ] val[i] val[i] 等于第 i i i 个点到跟节点的虚链个数 + 1 +1 +1,每棵 S p l a y Splay Splay 树维护的是具有相同颜色的节点的集合。初始状态下每个节点代表一颗 S p l a y Splay Splay v a l [ i ] = d e p [ i ] val[i] = dep[i] val[i]=dep[i]

由树上差分的思想,可以得到 v a l ( i , j ) = v a l [ i ] + v a l [ j ] − 2 ∗ v a l [ L C A ( i , j ) ] + 1 val (i, j) = val[i] + val[j] - 2 * val[LCA (i, j)] + 1 val(i,j)=val[i]+val[j]2val[LCA(i,j)]+1,(注意这里是在把路径权值转换成路径上虚链个数的前提下才成立的) 。

对于操作三,若按照 d f n dfn dfn 序建一棵线段树,则问题转化为求区间内最大值。

维护 v a l [ i ] val[i] val[i] 数组: A c c e s s Access Access 操作时,每次虚实链转变时,要分别找到虚实链的端点 ( S p l a y Splay Splay 树里一直跳左儿子即可),对子树内的 v a l [ i ] val[i] val[i] 均加一或减一。

AC代码:

#include <bits/stdc++.h>
#define ll long long
#define int ll
using namespace std;
const int maxn = 1e5 + 5;

int n, m, tot;
int fa1[maxn], fa2[maxn], siz[maxn], son[maxn], dep[maxn];
int top[maxn], dfn[maxn], rk[maxn], bot[maxn];
int mx[maxn << 2], ls[maxn << 2], rs[maxn << 2], lazy[maxn << 2];
int ch[maxn][2];
vector <int> adj[maxn];

void dfs1 (int f, int u, int d) {
	fa1[u] = f, siz[u] = 1, dep[u] = d;
	for (auto it : adj[u]) {
		if (it == f) continue;
		dfs1 (u, it, d + 1);
		siz[u] += siz[it];
		if (siz[it] > siz[son[u]]) son[u] = it;
	}
}

int dfs2 (int f, int u, int tp) {
	top[u] = tp;
	dfn[u] = ++tot, rk[tot] = u, bot[u] = tot;
	if (son[u]) bot[u] = max (bot[u], dfs2 (u, son[u], tp));
	for (auto it : adj[u]) {
		if (it == f || it == son[u]) continue;
		bot[u] = max (bot[u], dfs2 (u, it, it));
	}
	return bot[u];
}

int lca (int x, int y) {
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap (x, y);
		x = fa1[top[x]];
	}
	return dep[x] < dep[y] ? x : y;
}

void update (int cnt) {mx[cnt] = max (mx[ls[cnt]], mx[rs[cnt]]);}

void build (int cnt, int l, int r) {
	if (l == r) {
		mx[cnt] = dep[rk[l]];
		lazy[cnt] = 0;
		return;
	}
	int mid = l + r >> 1;
	build (ls[cnt] = ++tot, l, mid);
	build (rs[cnt] = ++tot, mid + 1, r);
	update (cnt);
}

void pushdown (int cnt) {
	mx[ls[cnt]] += lazy[cnt];
	mx[rs[cnt]] += lazy[cnt];
	
	lazy[ls[cnt]] += lazy[cnt];
	lazy[rs[cnt]] += lazy[cnt];	
	
	lazy[cnt] = 0;
}

void add (int cnt, int l, int r, int ql, int qr, int k) {
	if (l >= ql && r <= qr) {
		lazy[cnt] += k;
		mx[cnt] += k;
		return;
	}
	pushdown (cnt);
	int mid = l + r >> 1;
	if (ql <= mid) add (ls[cnt], l, mid, ql, qr, k);
	if (qr > mid) add (rs[cnt], mid + 1, r, ql, qr, k);
	update (cnt);
}

int query (int cnt, int l, int r, int ql, int qr) {
	if (l >= ql && r <= qr) return mx[cnt];
	pushdown (cnt);
	int mid = l + r >> 1;
	int res = -1;
	if (ql <= mid) res = max (res, query (ls[cnt], l, mid, ql, qr));
	if (qr > mid) res = max (res, query (rs[cnt], mid + 1, r, ql, qr));
	return res;
}

namespace LCT {
	bool Get (int x) {return x == ch[fa2[x]][1];}
	bool isRoot (int x) {return x != ch[fa2[x]][0] && x != ch[fa2[x]][1];}
	
	void Rotate (int x) {
		int y = fa2[x], z = fa2[y], chk = Get (x);
		if (!isRoot (y)) ch[z][Get (y)] = x;
		if (ch[x][chk ^ 1]) fa2[ch[x][chk ^ 1]] = y;
		ch[y][chk] = ch[x][chk ^ 1];
		ch[x][chk ^ 1] = y;
		fa2[y] = x, fa2[x] = z;
	}
	
	void Splay (int x) {
		for (int f = fa2[x]; f = fa2[x], !isRoot (x); Rotate (x)) {
			if (!isRoot (f)) Rotate (Get (f) == Get (x) ? f : x);
		}
	}
	
	int findRoot (int x) {
		while (ch[x][0]) x = ch[x][0];
		return x;
	}
	
	int Access (int x) {
		int last, tmp;
		for (last = 0; x; last = x, x = fa2[x]) {
			Splay (x);
			if (ch[x][1]) {
				tmp = findRoot (ch[x][1]);
				add (0, 1, n, dfn[tmp], bot[tmp], 1);
			}
			if (last) {
				tmp = findRoot (last);
				add (0, 1, n, dfn[tmp], bot[tmp], -1);
			}
			ch[x][1] = last;
		}
		return last;
	}
	
}

void init () {}

void charming () {
	init ();
	cin >> n >> m;
	for (int i = 1, u, v; i < n; ++i) {
		cin >> u >> v;
		adj[u].emplace_back (v);
		adj[v].emplace_back (u);
	}
	dfs1 (0, 1, 1);
	dfs2 (0, 1, 1);
	tot = 0;
	build (0, 1, n);
	for (int i = 1; i <= n; ++i) fa2[i] = fa1[i];
	int opt, x, y, LCA, val1, val2, val3;
	for (int i = 1; i <= m; ++i) {
		cin >> opt >> x;
		if (opt == 1) LCT :: Access (x);
		else if (opt == 2) {
			cin >> y;
			LCA = lca (x, y);
			val1 = query (0, 1, n, dfn[x], dfn[x]);
			val2 = query (0, 1, n, dfn[y], dfn[y]);
			val3 = query (0, 1, n, dfn[LCA], dfn[LCA]);
			cout << val1 + val2 - (val3 << 1) + 1 << endl;
		}
		else cout << query (0, 1, n, dfn[x], bot[x]) << endl;
	}
}

signed main () {
	charming ();
	return 0;
}

收获&总结

L C T LCT LCT 建模也很重要,这次算是见识到一种方法了。

另外本题不能使用 S p l i t Split Split 操作,因为会换根,导致我们 S p l a y Splay Splay 维护同一种颜色的点的集合的性质就被破坏了。

所以这道题 L C T LCT LCT 只能通过 A c c e s s Access Access 操作起建模作用。

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

[SDOI2017]树点涂色 的相关文章

  • 删除文件的最后 10 个字符

    我想删除文件的最后 10 个字符 说一个字符串 hello i am a c learner 是文件内的数据 我只是希望该文件是 hello i am a 文件的最后 10 个字符 即字符串 c learner 应在文件内消除 解决方案 将
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置

随机推荐

  • 移动H2-3获取超管密码

    本文主要参考自 https www bilibili com read cv18292443 确保能正常访问光猫后台 192 168 1 1 然后用浏览器打开 http 192 168 1 1 webcmcc gui device info
  • 物联网技术及应用计算机,物联网的关键技术及计算机物联网的应用

    关键词 计算机 物联网 关键技术 应用 1 物联网的相关介绍 1 1 物联网的概念 物联网 Internet of things 是科技高速发展的产物 也是信息时代发展的象征 从字面意思来看 物联网就是通过互联网将相同的或者不同的物体连接起
  • 数据库系统原理———两段锁协议、死锁练习题

    一 题目描述 14 考虑T和T2两个事务 T1 R A R B B A B W B T2 R B R A A A B W A 1 改写T和T2 增加加锁操作和解锁操作 并要求遵循两阶段封锁协议 2 说明T和T2的执行是否会引起死锁 给出T和
  • Go语言创始人从Google离职

    点击关注公众号 互联网架构师 后台回复 2T获取2TB学习资源 上一篇 Alibaba开源内网高并发编程手册 pdf 前两天 谷歌Go语言产品负责人Steve Francia突然宣布离职 并回顾总结自己在谷歌的6年生涯经历 以及分享了离开的
  • Selenium成长之路-07简单对象定位之tag name方法

    继续学习元素定位 tag name 每个前端开发人员 都有自己的习惯 所以 不一定每一个开发人员都喜欢用id name来做标签 所以我们就需要掌握其他的定位方法 例如tag name 下面我们继续来进行百度首页的定位 可以看到首页下图中红框
  • linux命令---GNU awk介绍

    概述 gawk是GNU工程 是一种编程语言 它实现了标准awk的所有功能 用于在linux unix下对文本和数据进行处理 数据可以来自标准输入 stdin 一个或多个文件 或其它命令的输出 它支持用户自定义函数和动态正则表达式等先进功能
  • Qt 使用openssl库

    在windows下面 QT开发使用ssl库一开始总会有些问题 这里记录一下最近解决的找不到库的经过 安装QT时如果选择了支持openssl 那么qt就会编译一个版本的openssl库 通常会放在几个地方 这里就不多说了 在安装目录找一找就是
  • PTAL1-016 查验身份证 c++实现 多种方法 多种细节

    目录 先上代码 我遇到的问题 首先 对题目的理解 其次 是对代码的优化问题 最后 返回值 多种解法 1 换种数据结构 2 back 函数 3 类 先上代码 include
  • 如何在app store营销之实战技巧(6)

    是的 偶不算程序员 试头像 秀一下业娱作品 第520贴 献给我爱的XXX google docs被墙了 chrome os 2009 iPhone全球技术巡讲 北京站参会确认 邮件收到了 哈哈 恭喜Dr Stone Wars Lite升级啦
  • vue实现给页面添加水印

    第一步 先封装以下文件 创建utils watermark js文件 水印添加方法 let setWatermark str1 str2 gt let id 1 23452384164 123412415 if document getEl
  • 华为机试练习(十)求第K多连续重复子串

    题目描述 给定字符串 str 和正数 K 求出现次数第 k 多的重复的子串 样例输入 AAAAHHHBBCDHHHH 3 样例输出 2 说明 A 4 H 4 H 3 B 2 C 1 D 1 求第3次数多的 本来应该是H 但是由于H在之前已经
  • JS实现注册登录发送短信验证码动态显示60S倒计时完整案例

    通常在web项目中都会遇到账户注册或者忘记密码时需要发送短信验证码的功能 虽然说这种功能很常见 但是实际开发过程中很多人还会遇到不少坑 笔者经过整理把最近项目中的用到的这个发送短信验证码动态显示60S倒计时的完整实现过程分享给广大开发者朋友
  • Spring 整合 MyBatis

    前文介绍了Spring最基本的功能 Spring是一个DI 依赖注入 容器和AOP 面向切面 容器 但这仅仅是手段 远不是目标 Spring的目标是整合与简化其他Java框架的开发 通过DI管理其他框架和组件 利用AOP分离繁复部分 使得复
  • 帮我写个matlab输出扫频信号的代码

    当然 我可以帮你写一个Matlab输出扫频信号的代码 以下是一个简单的例子 定义扫频信号的起始频率 结束频率和时间间隔 f start 0 f end 1000 t step 0 001 生成时间序列 t 0 t step 1 生成扫频信号
  • vue 上传多个文件显示进度条

    组件A中的上传功能
  • docker-compose 安装nacos(单机版本)

    https gitee com yuanshuai likeit nacos docker git cd usr local docker git clone https gitee com yuanshuai likeit nacos d
  • react 图像识别_无法在React中基于URL查找图像

    react 图像识别 If you re new to React and are having trouble accessing images stored locally you re not alone 如果您不熟悉React 并且
  • python+selenium 浏览器无界面模式运行

    以Chrome浏览器为例 方法一 from selenium webdriver import Chrome ChromeOptions opt ChromeOptions 创建Chrome参数对象 opt headless True 把C
  • Redis主从复制时master_link_status:down的问题

    Redis进行主从复制时 在6380端口使用slaveof 127 0 0 1 6379 结果出现master link status down的问题 出现这个情况是由于主机使用有密码 需要在从机的配置文件redis6380 conf加入m
  • [SDOI2017]树点涂色

    洛谷 SDOI2017 树点涂色 题目描述 Bob 有一棵 n n n 个点的有根树 其中 1 1 1 号点是根节点 Bob 在每个点上涂了颜色 并且每个点上的颜色不同 定义一条路径的权值是 这条路径上的点 包括起点和终点 共有多少种不同的