比较傻逼的一道题...

  显然求子树最小值就是求出dfs序用线段树维护嘛

  换根的时候树的形态不会改变,所以我们可以根据相对于根的位置分类讨论。

  如果询问的x是根就直接输出整棵树的最小值。

  如果询问的x是根在原树上的子节点,直接输出子树的最小值。

  如果询问的x是根在原树上的祖先,那么就要输出整棵树去掉x在原树上那个包含根的子节点的子树的答案。

  至于怎么求x在原树上那个包含根的子节点,可以用倍增。

  但是我发现直接遍历x的子节点居然不会被卡,而且还跑到了第一页嘿嘿嘿

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
const int maxn=, inf=1e9;
struct poi{int too, pre;}e[maxn];
struct tjm{int sum;}tree[maxn<<];
int n, q, x, y, tot, tott, root;
int a[maxn], last[maxn], l[maxn], r[maxn], pos[maxn], d[maxn], f[maxn][];
char s[];
inline void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-' && (f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
inline void add(int x, int y){e[++tot].too=y; e[tot].pre=last[x]; last[x]=tot;}
void dfs(int x)
{
l[x]=++tott; pos[tott]=x; d[x]=d[f[x][]]+;
for(int i=last[x];i;i=e[i].pre) f[e[i].too][]=x, dfs(e[i].too);
r[x]=tott;
}
inline int min(int a, int b) {return a<b?a:b;}
inline void up(int x) {tree[x].sum=min(tree[x<<].sum, tree[x<<|].sum);}
void build(int x, int l, int r)
{
if(l==r) {tree[x].sum=pos[l]?a[pos[l]]:inf; return;}
int mid=(l+r)>>;
build(x<<, l, mid); build(x<<|, mid+, r);
up(x);
}
void update(int x, int l, int r, int cx, int delta)
{
if(l==r) {tree[x].sum=delta; return;}
int mid=(l+r)>>;
if(cx<=mid) update(x<<, l, mid, cx, delta);
else update(x<<|, mid+, r, cx, delta);
up(x);
}
int query(int x, int l, int r, int cl, int cr)
{
if(cl>cr) return inf;
if(cl<=l && r<=cr) return tree[x].sum;
int mid=(l+r)>>, ans=inf;
if(cl<=mid) ans=query(x<<, l, mid, cl, cr);
if(cr>mid) ans=min(ans, query(x<<|, mid+, r, cl, cr));
return ans;
}
inline int solve(int x)
{
if(x==root) return tree[].sum;
if(l[x]>l[root] || r[x]<l[root]) return query(, , n, l[x], r[x]);
int now=root;
for(int i=;i>=;i--) if(d[f[now][i]]>x) now=f[now][i];
return min(query(, , n, , l[now]-), query(, , n, r[now]+, n));
}
int main()
{
read(n); read(q);
for(int i=;i<=n;i++)
{
read(x); read(a[i]);
if(x) add(x, i);
}
dfs(root=); build(, , n);
for(int j=;j<=;j++) for(int i=;i<=n;i++) f[i][j]=f[f[i][j-]][j-];
for(int i=;i<=q;i++)
{
scanf("%s", s+);
if(s[]=='V') read(x), read(y), update(, , n, l[x], y);
else if(s[]=='E') read(root);
else read(x), printf("%d\n", solve(x));
}
}

bzoj3306: 树(dfs序+倍增+线段树)的更多相关文章

  1. Codeforces 877E - Danil and a Part-time Job(dfs序+线段树)

    877E - Danil and a Part-time Job 思路:dfs序+线段树 dfs序:http://blog.csdn.net/qq_24489717/article/details/5 ...

  2. [bzoj3306]树_dfs序_线段树_倍增lca

    树 bzoj-3306 题目大意:给定一颗n个节点的树,支持换根.修改点权.查询子树最小值. 注释:$1\le n,q\le 10^5$. 想法: 如果没有换根操作,就是$dfs$序+线段树维护区间最 ...

  3. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

  4. bzoj2819 DFS序 + LCA + 线段树

    https://www.lydsy.com/JudgeOnline/problem.php?id=2819 题意:树上单点修改及区间异或和查询. 思维难度不高,但是题比较硬核. 整体思路是维护每一个结 ...

  5. 用dfs序处理线段树的好题吗?

    https://www.cnblogs.com/mountaink/p/9878918.html 分析:每次的选取必须选最优的一条链,那我们考虑一下选择这条链后,把这条路上的点的权值更新掉,再采取选最 ...

  6. 7月13日考试 题解(DFS序+期望+线段树优化建图)

    T1 sign 题目大意:给出一棵 N 个节点的树,求所有起点为叶节点的有向路径,其 上每一条边权值和的和.N<=10000 水题.考试的时候毒瘤出题人(学长orz)把读入顺序改了一下,于是很多 ...

  7. hdu 3974 Assign the task(dfs序上线段树)

    Problem Description There is a company that has N employees(numbered from 1 to N),every employee in ...

  8. Luogu P2982 [USACO10FEB]慢下来 Slowing down | dfs序、线段树

    题目链接 题目大意: 有一棵N个结点树和N头奶牛,一开始所有奶牛都在一号结点,奶牛们将按从编号1到编号N的顺序依次前往自己的目的地,求每头奶牛在去往自己目的地的途中将会经过多少已经有奶牛的结点. 题解 ...

  9. Codeforces Round #200 (Div. 1) D. Water Tree(dfs序加线段树)

    思路: dfs序其实是很水的东西.  和树链剖分一样, 都是对树链的hash. 该题做法是:每次对子树全部赋值为1,对一个点赋值为0,查询子树最小值. 该题需要注意的是:当我们对一棵子树全都赋值为1的 ...

随机推荐

  1. Ubuntu设置DNS服务

    有时候安装完Ubuntu系统,源换好好还是不能更新,软件也不能下, 配置好IP,ping 1.1.1.1是通的,ping 域名就不通了,这是没有DNS解析域名的结果 一.Server版: 对于Ubun ...

  2. Unity Lighting - Reflections 反射(六)

      Reflections 反射 Reflection Source 反射源 By default, objects in a scene are rendered using Unity’s ‘St ...

  3. Siki_Unity_2-2_NGUI_UI插件学习(3.6.8版本)(未学)

    Unity 2-2 NGUI UI插件学习(3.6.8版本)(未学)

  4. Python3基础-表达式和运算符

    表达式和运算符 什么是表达式? 1+2*3就是一个表达式,这里的加号和乘号叫做运算符,1.2.3叫做操作数. 1+2*3经过计算后得到的结果是7,我们可以将计算结果存放在一个变量里,result=1+ ...

  5. BVT与冒烟测试

    [BVT的释义] BVT的全称是Build Verification Test.可以说这个全称就是BVT的定义了. BVT只验证build构建的成功与失败,不深入测试构建好的build的功能.性能等等 ...

  6. Planning The Expedition(暴力枚举+map迭代器)

    Description Natasha is planning an expedition to Mars for nn people. One of the important tasks is t ...

  7. 0421--"数字口袋精灵app"二次开发(Blackbriar团队开发)

    "数字口袋精灵app"二次开发 目录: 一.项目github总仓库推送 二.开发成员 三.分工与合作 四.各模块成果 五.心得墙 六.团队成员贡献分 内容: 一.项目github总 ...

  8. 第10次Scrum会议(10/22)【欢迎来怼】

    一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华小组照片 二.开会信息 时间:2017/10/22 17:20~17:33,总计13min.地点:东北师范 ...

  9. Java 学习笔记 ------第二章 从JDK到IDE

    本章学习目标: 了解与设定PATH 了解与指定CLASSPATH 了解与指定SOURCEPATH 使用package与import管理类别 初步认识JDK与IDE的对应关系 一.第一个Java程序 工 ...

  10. 漫漫征途,java开发(未完待续)

    前言 2018年,大二上,有幸加入服务外包实验室的考核,在考核中,主动加入xxx项目的后端,一是为了积累项目经验,二是为了学到更多东西,进入了之后发现原来要学的这么多,时间这么紧!但唯有学习! 心得体 ...