[Luogu] 遥远的国度
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] 遥远的国度的更多相关文章
- 【luogu P3979 遥远的国度】 题解
题目链接:https://www.luogu.org/problemnew/show/P3979 除了换根操作都是裸的树剖 所以换根时考虑: 1.我查询的根等于换的根:无影响 2.我查询的根是换的根的 ...
- Luogu 3979 遥远的国度
树剖已经是人尽皆知的sb题了吗…… 很早以前就想填掉这坑了…… 考虑到树链唯一,进行操作并不会对换根产生影响,那么我们的换根操作只要记下root在哪里就好了 询问的时候分类讨论: 1:root == ...
- 【Luogu】P3979遥远的国度(树链剖分)
题目链接 不会换根从暑假开始就困扰我了……拖到现在…… 会了还是很激动的. 换根操作事实上不需要(也不能)改树剖本来的dfs序……只是在query上动动手脚…… 设全树的集合为G,以root为根,u在 ...
- [luogu3979][bzoj3083]遥远的国度
[luogu传送门] [bzoj传送门] 题目描述 zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcww ...
- Luogu 1514 引水入城 (搜索,动态规划)
Luogu 1514 引水入城 (搜索,动态规划) Description 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N行M列的矩形,如上图 ...
- [luogu]P1514 引水入城[搜索][记忆化][DP]
[luogu]P1514 引水入城 引水入城 题目描述在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形 ,如下图所示,其中每个格 ...
- BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 1280 MBSubmit: 3127 Solved: 795[Submit][Status][Discu ...
- Luogu 魔法学院杯-第二弹(萌新的第一法blog)
虽然有点久远 还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题 沉迷游戏,伤感情 #include <queue> ...
- luogu p1268 树的重量——构造,真正考验编程能力
题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...
随机推荐
- adb链接时报错误10061解决方法
首先打开开发者选项然后依次操作: 1. 将安卓设备usb连接到电脑 2. 设备链接到wifi 3. Ping设备ip,检查是否可通信 4. 在cmd依次输入以下命令: 5. adb usb 6. ad ...
- PHP运行机制和原理
以echo "Hello World";为例 经历五个步骤:1.扫描(scanning):先进行语法分析和词法分析,然后将index.php内容变成一个个语言片段(token ar ...
- awr报告没有数据11.2.0.3
有个朋友,反馈AWR没有数据: 咨询版本:oracle企业版本11.2.0.3 SQL> select * from v$version; BANNER -------------------- ...
- Asp.Net Mvc项目添加WebApi
1.添加一个WebApi 空项目 2.删除WebApi项目下的 Global.asax 文件,因为我们要把WebApi项目整合到Mvc项目中去,全局只需要一个Global 3.修改 WebApi 项目 ...
- mac安装composer
推荐阅读:https://www.jianshu.com/p/edde14a67b1a 自己实际操作: 下载 composer https://getcomposer.org/download/ 下载 ...
- 使用Lua编写Wireshark插件解析KCP UDP包,解析视频RTP包
前段时间写了一个局域网音视频通话的程序,使用开源 KCP 来实现可靠UDP传输. 通过研究发现KCP在发包时,会在数据包前面加上它自己的头.如果数据包较小,KCP可能会把多个数据包合成一个包发送,提高 ...
- SVN 问题解决之 Working copy path does not exist in repository
同事的SVN更新时提示某个特定文件提示 Working copy path does not exist in repository svn更新会被这个错误打断,导致无法完全更新 删掉文件再更新仍然有 ...
- AngularJS入门教程之与服务器(Ajax)交互操作示例
AngularJS从Web服务器请求资源都是通过Ajax来完成,所有的操作封装在$http服务中,$http服务是只能接收一个参数的函数,这个参数是一个对象,用来完成HTTP请求的一些配置,函数返回一 ...
- C++——数组形参退化为指针
数组做形参退化为指针 如果数组作为函数参数,则数组形参会退化为指针,以下代码在编译器看来是等价的 ]); ]); void fun3(int a[]); void fun4(int *a); #inc ...
- SVN将项目代码加入svn版本控制
将已有项目代码加入svn版本控制 - TortoiseSVN入门篇Windows下SVN实用教程(以TortoiseSVN作为客户端(client)) 翻译: Bravo Young Next: 版本 ...