「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 语言,还是在刚进入大学的时候,算起来有好些 ...
随机推荐
- JavaSE复习~方法基础
方法的概念 方法:就是讲一个功能抽取出来,把代码单独定义在其中,形成一个单独的功能 我们需要这个功能的时候,就可以去调用,实现了代码的复用性,也解决了代码冗余的问题 方法的定义 定义的一般格式:jav ...
- ArrayList,LinkedList,vector的区别
1,Vector.ArrayList都是以类似数组的形式存储在内存中,LinkedList则以链表的形式进行存储. 2.List中的元素有序.允许有重复的元素,Set中的元素无序.不允许有重复元素. ...
- 【PAT甲级】1045 Favorite Color Stripe (30 分)(DP)
题意: 输入一个正整数N(<=200),代表颜色总数,接下来输入一个正整数M(<=200),代表喜爱的颜色数量,接着输入M个正整数表示喜爱颜色的编号(同一颜色不会出现两次),接下来输入一个 ...
- DNS域名解析服务(重点)
一 .DNS 系统的作用 1.DNS 服务器概述 DNS 系统在网络中的作用就是维护着一个地址数据库,其中记录了各种主机域名:与 IP地址的对应关系,以便为客户程序提供正向或反向的地址查询服务,即正 ...
- Python3.5学习之旅——day4
本节内容 1.装饰器 2.迭代器与生成器 3.内置方法 4.软件目录结构规范 一.装饰器 装饰器是一个用来装饰其他函数的工具,即为其他函数添加附加功能,其本质就是函数. 装饰器需要遵循的以下两个原则: ...
- Python 爬取的类封装【将来可能会改造,持续更新...】(2020年寒假小目标09)
日期:2020.02.09 博客期:148 星期日 按照要求,我来制作 Python 对外爬取类的固定部分的封装,以后在用 Python 做爬取的时候,可以直接使用此类并定义一个新函数来处理CSS选择 ...
- Write-Up-wakanda-1
关于 下载地址:点我 哔哩哔哩:哔哩哔哩 祖传开头 信息收集 这里用vm虚拟机可能有一点问题,因为官方的是用vbox虚拟机导出的镜像文件.所以这次使用vbox虚拟机. ➜ ~ ip a show de ...
- 数字统计(0)<P2010_1>
数字统计 (two.pas/c/cpp) [问题描述] 请统计某个给定范围[L, R]的所有整数中,数字 2 出现的次数. 比如给定范围[2, 22],数字 2 在数2中出现了 1次,在数 12 ...
- 记录6--Java栈堆
class Person { int age; } public class LearnHeap { public static void main(String args[]){ int a=18; ...
- python爬虫(三) 用request爬取拉勾网职位信息
request.Request类 如果想要在请求的时候添加一个请求头(增加请求头的原因是,如果不加请求头,那么在我们爬取得时候,可能会被限制),那么就必须使用request.Request类来实现,比 ...