「LuoguP3979」遥远的国度
传送门
Luogu
解题思路
带换根操作的树剖。
换根只会影响更新或查询子树信息的操作。
我们始终保持初始的根不变,然后只要分类讨论一下:
假设当前被查询的节点是 \(u\)
- 如果 \(u\) 就是根节点,直接询问整棵树;
- 如果 \(u\) 不是根,且不是初始根的祖先,直接查询子树即可;
- 如果 \(u\) 是根的祖先,那么我们就找到 \(u\) 到根这条路径上的第一个儿子,然后分开查询即可
至于怎么分开查询,自己yy一下就好了。
细节注意事项
- 咕咕咕
参考代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while (!isdigit(c)) f |= (c == '-'), c = getchar();
while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
s = f ? -s : s;
}
const int _ = 100010;
int tot, head[_], nxt[_ << 1], ver[_ << 1];
inline void Add_edge(int u, int v)
{ nxt[++tot] = head[u], head[u] = tot, ver[tot] = v; }
int n, m, rt, val[_];
int dep[_], siz[_], son[_], fa[_];
int top[_], dfn[_], rev[_];
int mn[_ << 2], tag[_ << 2];
inline int lc(int p) { return p << 1; }
inline int rc(int p) { return p << 1 | 1; }
inline void pushup(int p) { mn[p] = min(mn[lc(p)], mn[rc(p)]); }
inline void f(int p, int v) { mn[p] = tag[p] = v; }
inline void pushdown(int p)
{ if (tag[p]) f(lc(p), tag[p]), f(rc(p), tag[p]), tag[p] = 0; }
inline void build(int p = 1, int l = 1, int r = n) {
tag[p] = 0; if (l == r) { mn[p] = val[rev[l]]; return ; }
int mid = (l + r) >> 1;
build(lc(p), l, mid), build(rc(p), mid + 1, r), pushup(p);
}
inline void update(int ql, int qr, int v, int p = 1, int l = 1, int r = n) {
if (ql <= l && r <= qr) return f(p, v);
int mid = (l + r) >> 1;
pushdown(p);
if (ql <= mid) update(ql, qr, v, lc(p), l, mid);
if (qr > mid) update(ql, qr, v, rc(p), mid + 1, r);
pushup(p);
}
inline int query(int ql, int qr, int p = 1, int l = 1, int r = n) {
if (ql <= l && r <= qr) return mn[p];
int mid = (l + r) >> 1, res = 2147483647;
pushdown(p);
if (ql <= mid) res = min(res, query(ql, qr, lc(p), l, mid));
if (qr > mid) res = min(res, query(ql, qr, rc(p), mid + 1, r));
return res;
}
inline void dfs1(int u, int f) {
siz[u] = 1, fa[u] = f, dep[u] = dep[f] + 1;
for (rg int v, i = head[u]; i; i = nxt[i])
if (!dep[v = ver[i]]) {
dfs1(v, u), siz[u] += siz[v];
if (siz[son[u]] < siz[v]) son[u] = v;
}
}
inline void dfs2(int u, int topf) {
top[rev[dfn[u] = ++dfn[0]] = u] = topf;
if (!son[u]) return; dfs2(son[u], topf);
for (rg int v, i = head[u]; i; i = nxt[i])
if (!top[v = ver[i]]) dfs2(v, v);
}
inline int pson(int x, int y){
int fx = top[x], fy = top[y];
while (fx != fy){
if (dep[fx] < dep[fy]) swap(x, y), swap(fx, fy);
if (fa[fx] == y) return fx; x = fa[fx], fx = top[x];
}
return dep[x] < dep[y] ? son[x] : son[y];
}
inline int LCA(int x, int y) {
int fx = top[x], fy = top[y];
while (fx != fy) {
if (dep[fx] < dep[fy]) swap(x, y), swap(fx, fy);
x = fa[fx], fx = top[x];
}
return dep[x] < dep[y] ? x : y;
}
inline void uptRange(int x, int y, int v) {
int fx = top[x], fy = top[y];
while (fx != fy) {
if (dep[fx] < dep[fy]) swap(x, y), swap(fx, fy);
update(dfn[fx], dfn[x], v), x = fa[fx], fx = top[x];
}
if (dep[x] > dep[y]) swap(x, y);
return update(dfn[x], dfn[y], v);
}
inline int qSon(int x) {
if (rt == x) return query(1, n);
int lca = LCA(rt, x);
if (lca != x) return query(dfn[x], dfn[x] + siz[x] - 1);
int t = pson(rt, x);
return min(query(1, dfn[t] - 1), query(dfn[t] + siz[t], n));
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
#endif
read(n), read(m);
for (rg int u, v, i = 1; i < n; ++i)
read(u), read(v), Add_edge(u, v), Add_edge(v, u);
for (rg int i = 1; i <= n; ++i) read(val[i]);
read(rt), dfs1(rt, 0), dfs2(rt, rt), build();
for (int opt, x, y, v; m--; ) {
read(opt);
if (opt == 1) read(rt);
else if (opt == 2) read(x), read(y), read(v), uptRange(x, y, v);
else if (opt == 3) read(x), printf("%d\n", qSon(x));
}
return 0;
}
完结撒花 \(qwq\)
「LuoguP3979」遥远的国度的更多相关文章
- 「BZOJ3083」遥远的国度(树剖换根
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 4859 Solved: 1372[Submit][Status][Discu ...
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- 「C++」理解智能指针
维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...
- 「JavaScript」四种跨域方式详解
超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...
- 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management
写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...
- 「2014-3-18」multi-pattern string match using aho-corasick
我是擅(倾)长(向)把一篇文章写成杂文的.毕竟,写博客记录生活点滴,比不得发 paper,要求字斟句酌八股结构到位:风格偏杂文一点,也是没人拒稿的.这么说来,arxiv 就好比是 paper 世界的博 ...
- 「2014-3-17」C pointer again …
记录一个比较基础的东东-- C 语言的指针,一直让人又爱又恨,爱它的人觉得它既灵活又强大,恨它的人觉得它太过于灵活太过于强大以至于容易将人绕晕.最早接触 C 语言,还是在刚进入大学的时候,算起来有好些 ...
随机推荐
- CSS样式的优先级(权重)
当使用不同的选择器选中同一个元素并设置相同样式时,这时样式间产生了冲突 最终采用的是哪个选择器? 由选择器的优先级(权重)决定,权重高的优先显示 优先级规则(多个按位置分别进行计算,不进位): 内联样 ...
- 【快学Docker】快速创建容器,容器常用命令
前言 容器是Docker的三大核心概念之一.简单地说,容器是独立运行的一个或一组应用,以及它们的运行态环境.对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面 ...
- Navicat for MySQL怎么往表中填数据
只有往表中更新数据,数据库才会起到真正的作用. 工具/原料 仔细阅读 方法/步骤 1.打开数据库,首先连接localhost,如图所示. 2.连接成功后,右侧便会显示已经建成的表,找到要修改的表, ...
- 九、Appium-python-UI自动化之通过text定位
1.通过xpath定位text xpath路径为://android.widget.EditText[@text='请输入包含街道的完整地址'] 2.通过AndroidUIAutomator # 这个 ...
- 关于null和空指针异常
1,null是一个标识符,用来表示不确定的对象,可以将null赋给引用类型变量,但不可以将null赋给基本类型变量 2,null本身不是对象,也不是object的实例,也不知道是什么类型 3,对于集合 ...
- 找到第N个字符
找到第N个字符 小黑黑上课的时候走神儿,鬼使神差的就想到了这么一个问题,假如: S1=a S2=ab S3=abc S4=abcd S26=abcdefghijklmnopqrstuvwxy ...
- GO第归
Go 语言递归函数 递归,就是在运行的过程中调用自己. 语法格式如下: func recursion() { recursion() /* 函数调用自身 */ } func main() { ...
- java集合知识点
若不重写equals方法,则调用的是object对象的equals方法,相当于==比较,比较的是对象的内存地址 |------Collection接口:单列集合,用来存储一个一个对象 |------L ...
- 吴裕雄 python 神经网络——TensorFlow 实现LeNet-5模型处理MNIST手写数据集
import os import numpy as np import tensorflow as tf from tensorflow.examples.tutorials.mnist import ...
- 炼金术(1): 识别项目开发中的ProtoType、Demo、MVP
软件开发是很分裂的,只有不断使用原则和规律,才能带来质量. 只要不是玩具性质的项目,项目应该可以大概划分为0-1,1-10,10-100,100-1000四个种重要阶段.其中,0-1是原型验证性的:1 ...