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. Neo4j查询语句总结

    最近一直在做图数据库的相关工作,对neo4j的查询语言Cypher使用较多,故在此总结记录.Cypher作为图数据库的查询语言,感觉和关系型数据库的查询语言sql差不多吧. 1.如何找到一个节点x,x ...

  2. (七)easyUI之Accordion折叠面板:普通的静态面板

    一.普通的静态面板 前台 <%@ page language="java" contentType="text/html; charset=UTF-8" ...

  3. sys.dm_exec_query_stats的total_worker_time的单位是微秒还是毫秒

    该视图sys.dm_exec_query_stats存放的就是当前所有执行计划的详细信息,比如某条执行计划共占CPU多少等等.因为该视图对编译次数.占用CPU资源总量.执行次数等都进行了详细的记录,所 ...

  4. ulimit用法

    ulimit -a:显示当前所有的资源限制 -c:core文件大小 -f:设置创建文件的最大值 -n:设置内核可以同时打开的文件描述符的最大值 -p:设置管道缓冲区的最大值 -s:设置堆栈的最大值 - ...

  5. go语言interface学习

    Go 中的 interface 所具有的最基本的功能:作为一种 abstract type,实现各种 concrete type 的行为统一. interface是一种类型.只有是实例化后才能调用in ...

  6. IT 界那些朗朗上口的“名言”

    中国有很多古代警世名言,朗朗上口,凝聚了很多故事与哲理.硅谷的互联网公司里头也有一些这样的名言,凝聚了很多公司价值观和做事的方法,对于很多程序员来说,其影响潜移默化! Stay hungry Stay ...

  7. man 手册--nc

    man 手册--nc NCAT(1) Ncat Reference Guide NCAT(1) NAME ncat - Concatenate and redirect sockets SYNOPSI ...

  8. Aop动态代理和cglib

    一般我们使用Aop对象时,常用动态代理模式,即是采用映射一个相同的类在此基础上进行前置后置操作. 动态代理多是采用原类实现父类接口,然后动态代理一个和原类相同的双胞胎兄弟类来实现映射. 父类 publ ...

  9. Linux命令——shutdown、halt、poweroff、reboot、cal、date

    shutdown shutdown在关机的时候会通知所有用户 shutdown –r now 现在重启 shutdown now 现在关机 shutdown +5 过5分钟关机 shutdown –c ...

  10. flash多进程写操作

    1 应用场景介绍   硬件条件:使用stm32 MCU   软件条件:协议栈应用   协议栈简单介绍如下:   类似于OSI七层模型,所涉及的协议栈包括应用层,网络层,链路层,物理层,如下图:   在 ...