换根的树剖

https://www.luogu.org/problem/P3979

题意:

(出题人口活好....

给定一棵以 root 为根的 n 个点的有根树,对于任意一个点 x, 给定他

的点权 val。

现在请你完成以下操作

• 1 x 表示把当前有根树的根换为 x

• 2 x y val 表示把从 x 到 y 路径上的点点权设置为 val

• 3 x 询问 x 的子树内(包括 x)点权的最小值,并输出最小值。

分析

我们直接来考虑换根操作:

首先,dfs重新树剖是不现实的。然后,操作2和换根没啥关系,直接做。

所以我们直接考虑操作3,先对点1进行树剖,再设当前的根是root。

  1. 当x==root:全局最小,直接输出。

  2. 当x是root在以1为根情况下的子树:谁是根对这个x的子树没有影响

  3. x不属于以上情况,但也不在1到root的链上,而在其他的支叉上:还是木有影响,自己手胡以下吧

  4. x在1到root的链上:这就是要处理的重点了。

先不管怎么求min,先看看分别该什么时候求min:

1就直接判断完事,2和3性质一样,而且4的条件最好判断(只要lca(x,root)==x即可),所以我们可以先判断4,剩下的就是2或3,即剩下的直接输出

考虑操作4, 在以1为根的情况下,我们如果要求x的子树信息,我们查询的是[in[x], out[x]]这段区间,而在以root为根的情况下,我们如果要求x的子树信息,那我们没有求的是那一段? 是x在root方向上的亲儿子及其子树。所以我们只需要找到这个亲儿子(我把它形象的成为最近公共儿子lcs), 然后查找区间[1, in[lcs]-1] ∪ [out[lcs]+1, n] 的信息即可

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 100000+9;
const int MAXM = MAXN<<1;
#define ll long long
#define inf 21474836489 int n,m,root;
struct node{
int deep, size, son, fa, tp ,in, out;
}a[MAXN];
int _clock; int head[MAXN], cnt;
struct seg{
int y, nxt;
}e[MAXM];
void add_edge(int x, int y) {
e[++cnt].y = y;
e[cnt].nxt = head[x];
head[x] = cnt;
} void dfs1(int x, int fa) {
a[x].fa = fa;
a[x].deep = a[fa].deep + 1;
a[x].size = 1;
for(int i = head[x]; i; i = e[i].nxt)
if(e[i].y != fa) {
dfs1(e[i].y, x);
a[x].size += a[e[i].y].size;
a[x].son = a[a[x].son].size > a[e[i].y].size ? a[x].son : e[i].y;
}
} ll arr[MAXN], pos[MAXN];
void dfs2(int x, int tp) {
a[x].tp = tp;
a[x].in = ++_clock;
pos[_clock] = arr[x];
if(a[x].son) dfs2(a[x].son, tp);
for(int i = head[x]; i; i = e[i].nxt)
if(e[i].y != a[x].fa && e[i].y != a[x].son) dfs2(e[i].y, e[i].y);
a[x].out = _clock;
} struct tree{
ll mi, set;
}tr[MAXN<<2]; void pushup(int o) {tr[o].mi = min(tr[o<<1].mi , tr[o<<1|1].mi);}
void build(int o, int l, int r) {
tr[o].set = -1;
if(l == r) {
tr[o].mi = pos[l];
return ;
}
int mid = (l+r)>>1;
build(o<<1, l, mid);
build(o<<1|1, mid+1, r);
pushup(o);
} void pushdown(int o) {
if(tr[o].set == -1) return ;
tr[o<<1].mi = tr[o<<1|1].mi = tr[o<<1].set = tr[o<<1|1].set = tr[o].set;
tr[o].set = -1;
}
void optset(int o, int l, int r, int ql, int qr, ll k) {
if(ql <= l && r <= qr) {
tr[o].set = tr[o].mi = k;
return ;
}
int mid = (l+r)>>1;
pushdown(o);
if(ql <= mid) optset(o<<1, l, mid, ql, qr, k);
if(mid < qr) optset(o<<1|1, mid+1, r, ql, qr, k);
pushup(o);
}
ll query(int o, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) return tr[o].mi;
int mid = (l+r)>>1;
pushdown(o);
ll ans = inf;
if(ql <= mid) ans = min(ans, query(o<<1, l, mid, ql, qr));
if(mid < qr) ans = min(ans, query(o<<1|1, mid+1, r, ql, qr));
return ans;
}
void ttt_update(int x, int y, ll z) {
while(a[x].tp != a[y].tp) {
if(a[a[x].tp].deep < a[a[y].tp].deep) swap(x,y);
optset(1, 1, n, a[a[x].tp].in, a[x].in, z);
x = a[a[x].tp].fa ;
}
if(a[x].deep > a[y].deep) swap(x,y);
optset(1, 1, n, a[x].in, a[y].in, z);
} int lca(int x, int y) {
while(a[x].tp != a[y].tp) {
if(a[a[x].tp].deep < a[a[y].tp].deep) swap(x,y);
x = a[a[x].tp].fa;
}
return a[x].deep < a[y].deep ? x : y;
}
int find_lcs(int x, int y) {//找x到y方向上的亲儿子
int last;
while(a[y].tp != a[x].tp) {
last = a[y].tp;
y = a[a[y].tp].fa;
}
if(y != x) last = a[x].son;
return last;
} int main() {
scanf("%d%d",&n,&m);
int x,y;
for(int i = 1; i < n; i++) {
scanf("%d%d",&x,&y);
add_edge(x,y);
add_edge(y,x);
}
for(int i = 1; i <= n; i++) scanf("%lld",&arr[i]);
scanf("%d",&root);
dfs1(1, 0);
dfs2(1, 1);
build(1, 1, n);
ll z;
int cmd;
int son;
for(int i = 1; i <= m; i++) {
scanf("%d",&cmd);
if(cmd == 1) {
scanf("%d", &root);
} else if(cmd == 2) {
scanf("%d%d%lld",&x,&y,&z);
ttt_update(x, y, z);
} else {
scanf("%d",&x);
if(x == root) printf("%lld\n", tr[1].mi);
else if(lca(x, root) == x) {
son = find_lcs(x, root);
printf("%lld\n",min(query(1, 1, n, 1, a[son].in-1), query(1, 1, n, a[son].out+1, n)) );
} else printf("%lld\n",query(1, 1, n, a[x].in, a[x].out));
}
}
}

luoguP3979 遥远的国度的更多相关文章

  1. luoguP3979 遥远的国度 LCT+multiset维护子树信息

    Code: #include<bits/stdc++.h> #define maxn 150000 #define ll long long #define inf 21474836470 ...

  2. luoguP3979 遥远的国度 树链剖分

    \(1, 2\)操作没什么好说的 对于\(3\)操作,分三种情况讨论下 \(id = rt\)的情况下,查整棵树的最小值即可 如果\(rt\)在\(1\)号点为根的情况下不在\(id\)的子树中,那么 ...

  3. 「LuoguP3979」遥远的国度

    传送门 Luogu 解题思路 带换根操作的树剖. 换根只会影响更新或查询子树信息的操作. 我们始终保持初始的根不变,然后只要分类讨论一下: 假设当前被查询的节点是 \(u\) 如果 \(u\) 就是根 ...

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

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

  5. BZOJ 3083: 遥远的国度 dfs序,树链剖分,倍增

    今天再做一天树的题目,明天要开始专攻图论了.做图论十几天之后再把字符串搞搞,区域赛前再把计几看看. 3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 128 ...

  6. BZOJ 3083 遥远的国度 树链剖分

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 797  Solved: 181[Submit][Status] Descrip ...

  7. BZOJ_3083_遥远的国度_树链剖分+线段树

    BZOJ_3083_遥远的国度_树链剖分 Description 描述 zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神Ra ...

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

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

  9. P3979 遥远的国度

    P3979 遥远的国度 思路 一开始我用这个函数得到左端点 int get_l(int x,int y) { if(top[x]==top[y]) return son[x]; int last=to ...

随机推荐

  1. 关于sql sp_send_dbmail 发送邮件的怪异问题

    存储过程,其实就是将sp_send_dbmail采用参数的方式发送邮件,存储过程如下: ALTER PROCEDURE [dbo].[SP_Email_Send] @EmailTo varchar(m ...

  2. echarts js报错 Cannot read property 'getAttribute' of null

    本文将为您描述如何解决 eharts.js报错 Uncaught TypeError: Cannot read property 'getAttribute' of null 的问题 根据报错信息查找 ...

  3. I2C协议学习笔记

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/wzt_007/article/detai ...

  4. 公司员工表示 nginx 之父被警方带走

    ZDNet 12 日报导,俄罗斯警方当天突击搜查了 NGINX 公司(nginx 服务器项目商业化公司)在莫斯科的办事处,并带走了 NGINX 公司联合创始人 Igor Sysoev 与 Maxim ...

  5. 201871010116-祁英红《面向对象程序设计(java)》第十三周学习总结

    博文正文开头格式:(2分) 项目 内容 <面向对象程序设计(java)> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://ww ...

  6. windows下配置ngnix服务器经常出现503问题解决办法

    自己网站在windows server2008下安装的ngnix,然后配置php,网站访问流量并不大,但是经常出现503问题.经过查看ngnix服务器错误日志,发现: (10061: No conne ...

  7. 央行辟谣未发行“DC/EP”和“DCEP” 法定数字货币仍在测试阶段

    http://www.sohu.com/a/354709423_100157595 近期,中国央行再度就法定数字货币发布公告,指出目前系统仍处于研究测试过程中,市场上交易“DC/EP”或“DCEP”均 ...

  8. DRF--重写views

    前戏 在前面几篇文章里,我们写了get请求,post请求,put请求,在来写个delete请求,大概如下. class BookView(APIView): # 查询所有的数据和post方法 def ...

  9. ROS Tricks

    Gazebo 第一次进入 Gazebo 会卡在开始界面,此时是在加载模型文件,为保证模型顺利加载,可以提前将模型文件下载并放在本地路径 ~/.gazebo/models 下,模型文件下载地址: htt ...

  10. 【Notepad++】notepad++主题和字体设置(非常好看舒服的)

    #效果图 1.字体:Courier New 字号:14号字体 2.字体:Consolas 字号:14号字体 #设置方法 1.设置---语言格式设置 2.选择主题,同时勾选“使用全局字体”“使用全局字体 ...