https://www.luogu.org/problemnew/show/P3979

3种情况

x=root,很显然此时应当查询整棵树

lca(root,x)!=x ,此时直接查询x的子树即可,与换根无关

lca(root,x)=x,此时我们应当查询与x相邻的节点中与root最近的点v在整棵树中的补集

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using namespace std; typedef long long ll;
typedef double dd;
const int maxn=;
const ll INF = (ll)1E14 + ; int h[maxn], n, m, top[maxn], lca[maxn][], son[maxn], edge, sz[maxn], dep[maxn];
int L[maxn], R[maxn], root, num, x, y, tx, ty, t, opt;
ll val, a[maxn]; struct Edge {
int to, ne;
} e[maxn * ]; struct Seg {
ll minn, same;
} seg[maxn << ]; void close() {
exit();
} void addedge(int x,int y) {
e[edge].to = y;
e[edge].ne = h[x];
h[x] = edge++;
} void dfs(int k,int from) {
sz[k] = ;
dep[k] = dep[from] + ;
son[k] = ;
for (int p=h[k]; p!=-; p=e[p].ne) {
int to = e[p].to;
if (to == from) continue;
lca[to][] = k;
for (int i=; i<=; i++)
lca[to][i] = lca[lca[to][i-]][i-];
dfs(to, k);
sz[k] += sz[to];
if (sz[to] > sz[son[k]]) son[k] = to;
}
} void build(int k,int from) {
L[k] = ++num;
top[k] = from;
if (son[k]) build(son[k], from);
for (int p=h[k]; p!=-; p=e[p].ne) {
int to = e[p].to;
if (to != lca[k][] && to != son[k])
build(to, to);
}
R[k] = num;
} int get_lca(int x,int y) {
if (dep[x] < dep[y]) swap(x, y);
int depth = dep[x] - dep[y];
for (int i=; i>=; i--)
if (depth & ( << i))
x = lca[x][i];
if (x == y) return x;
for (int i=; i>=; i--) {
if (lca[x][i] != lca[y][i]) {
x = lca[x][i];
y = lca[y][i];
}
}
return lca[x][];
} void pushup(int rt) {
seg[rt].minn = min(seg[rt<<].minn, seg[rt<<|].minn);
} void same(int rt,ll val) {
seg[rt].minn = val;
seg[rt].same = val;
} void pushdown(int rt) {
if (seg[rt].same) {
same(rt << , seg[rt].same);
same(rt << | , seg[rt].same);
seg[rt].same = ;
}
} void change(int L,int R,ll val,int l,int r,int rt) {
if (L <= l && r <= R) {
same(rt, val);
return;
}
int mid = (l + r) >> ;
pushdown(rt);
if (L <= mid)
change(L,R,val,lson);
if (mid + <= R)
change(L,R,val,rson);
pushup(rt);
} ll query(int L,int R,int l,int r,int rt) {
if (L > R) return INF;
if (L <= l && r <= R) {
return seg[rt].minn;
}
int mid = (l + r) >> ;
pushdown(rt);
ll ans = INF;
if (L <= mid)
ans = min(ans, query(L,R,lson));
if (mid + <= R)
ans = min(ans, query(L,R,rson));
pushup(rt);
return ans;
} void cc() {
tx = top[x];
ty = top[y];
while (tx != ty) {
if (dep[tx] < dep[ty]) {
swap(x, y);
swap(tx, ty);
}
change(L[tx], L[x], val, , n, );
x = lca[tx][];
tx = top[x];
}
if (dep[x] < dep[y])
swap(x, y);
change(L[y], L[x], val, , n, );
} void work() {
if (root == x) {
printf("%lld\n", seg[].minn);
return;
}
t = get_lca(root, x);
if (t != x) {
printf("%lld\n", query(L[x], R[x], , n, ));
return;
}
int depth = dep[root] - dep[x] - ;
int haha = root;
for (int i=; i>=; i--)
if (depth & ( << i))
haha = lca[haha][i];
printf("%lld\n", min(query(, L[haha] - , , n, ), query(R[haha] + , n, , n, )) );
} void init() {
scanf("%d %d",&n,&m);
memset(h, -, sizeof(h));
for (int i=; i<=n-; i++) {
scanf("%d %d",&x, &y);
addedge(x, y);
addedge(y, x);
}
for (int i=; i<=n; i++)
scanf("%lld",&a[i]);
dfs(, );
build(, );
for (int i=; i<=n; i++)
change(L[i], L[i], a[i], , n, );
scanf("%d",&root);
while (m--) {
scanf("%d",&opt);
if (opt == ) scanf("%d",&root);
if (opt == ) {
scanf("%d %d %lld",&x,&y,&val);
cc();
}
if (opt == ) {
scanf("%d",&x);
work();
}
}
} int main () {
init();
close();
return ;
}

[Luogu] 遥远的国度的更多相关文章

  1. 【luogu P3979 遥远的国度】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3979 除了换根操作都是裸的树剖 所以换根时考虑: 1.我查询的根等于换的根:无影响 2.我查询的根是换的根的 ...

  2. Luogu 3979 遥远的国度

    树剖已经是人尽皆知的sb题了吗…… 很早以前就想填掉这坑了…… 考虑到树链唯一,进行操作并不会对换根产生影响,那么我们的换根操作只要记下root在哪里就好了 询问的时候分类讨论: 1:root ==  ...

  3. 【Luogu】P3979遥远的国度(树链剖分)

    题目链接 不会换根从暑假开始就困扰我了……拖到现在…… 会了还是很激动的. 换根操作事实上不需要(也不能)改树剖本来的dfs序……只是在query上动动手脚…… 设全树的集合为G,以root为根,u在 ...

  4. [luogu3979][bzoj3083]遥远的国度

    [luogu传送门] [bzoj传送门] 题目描述 zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcww ...

  5. Luogu 1514 引水入城 (搜索,动态规划)

    Luogu 1514 引水入城 (搜索,动态规划) Description 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N行M列的矩形,如上图 ...

  6. [luogu]P1514 引水入城[搜索][记忆化][DP]

    [luogu]P1514 引水入城 引水入城 题目描述在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形 ,如下图所示,其中每个格 ...

  7. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  8. Luogu 魔法学院杯-第二弹(萌新的第一法blog)

    虽然有点久远  还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题  沉迷游戏,伤感情 #include <queue> ...

  9. luogu p1268 树的重量——构造,真正考验编程能力

    题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...

随机推荐

  1. IDEA GIT 忽略文件 最佳方式

    前言 转载一篇博客,简单,实用. 原文地址:intellij idea 忽略文件不提交 ps:下面均为转载博客的内容: 在intellij中忽略提交文件,分两种情况, 文件没有纳入版本管理 第一种,文 ...

  2. internal关键字

    internal修饰符可以用于类型或成员,使用该修饰符声明的类型或成员只能在同一程集内访问,接口的成员不能使用internal修饰符. 就是使用internal的类只能在同一个项目中使用,不能在别的项 ...

  3. [C#] LINQ之SelectMany和GroupJoin

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. mysql-8.0.16-winx64的最新安装教程

    最近刚学习数据库,首先是了解数据库是什么,数据库.数据表的基本操作,这就面临了一个问题,mysql的安装,我这里下载的是64位的,基于Windows的,以下是在我电脑上的安装过程,希望可以帮助到大家. ...

  5. jvm系列(十):如何优化Java GC「

    转自:https://www.cnblogs.com/ityouknow/p/7653129.html 本文由CrowHawk翻译,地址:如何优化Java GC「译」,是Java GC调优的经典佳作. ...

  6. Timestamp,Date和String的互相转换

    1.Timestamp,Date和String的互相转换 //Timestamp转换成String: Timestamp ts = new Timestamp(System.currentTimeMi ...

  7. 使用SQLAlchemy,以及问题处理

    https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0014021031294178 ...

  8. nc 命令

    目录 nc 命令 一.简介 二.案例 1.端口扫描 2.聊天 3.文件传输 4.目录传输 5.加密网络发送的数据 6.流视频 7.克隆一个设备 8.打开一个shell 9.反向shell 10.指定端 ...

  9. 剑指Offer编程题(python)——二叉树

    1.重建二叉树 """ 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如输入前序遍历序列{1,2,4 ...

  10. (1)openstack-Rabbitmq 集群部署

    一.前期准备   (1)条件:准备3台linux系统,确保配置好源,及epel源  yun1,yun2,yun3   (2)三台机器能够静态解析彼此   (3)设置可以无密钥登陆  ssh-keyge ...