题目描述

修改某条路径上的值以及询问子树的最小值都最树剖的基础操作,那么如何实现换根呢?

考虑一下三种情况:

1.rot=询问的子树x,答案就是整棵树的最小值
2.rot在x的子树里,只有rot到x这一条链上的的节点的子树会变
找到x在rot方向上的子节点,答案就是除去这棵子树的最小值
3.rot不在x的子树里,那么rot是谁对x的子树没有影响,答案不变

那么就在询问时分类讨论一下就好了

#include<complex>
#include<cstdio>
using namespace std;
const int INF=<<;
const int N=1e5+;
struct node{
int v,nxt;
}e[N<<];
int n,m,s,Enum,tim,rot;
int val[N],front[N],fa[N][];
int fat[N],dep[N],tid[N],son[N],siz[N],top[N],rank[N];
int tree[N<<],lazy[N<<];
inline int qread()
{
int x=,j=;
char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')j=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*j;
}
inline void Insert(int u,int v)
{
e[++Enum].v=v;
e[Enum].nxt=front[u];
front[u]=Enum;
}
void dfs1(int x)
{
siz[x]=;
fa[x][]=fat[x];
for(int i=front[x];i;i=e[i].nxt)
{
int v=e[i].v;
if(v==fat[x])continue;
fat[v]=x;
dep[v]=dep[x]+;
dfs1(v);
siz[x]+=siz[v];
if(siz[v]>siz[son[x]])
son[x]=v;
}
}
void dfs2(int x,int tp)
{
top[x]=tp;
tid[x]=++tim;
rank[tid[x]]=x;
if(!son[x])return;
dfs2(son[x],tp);
for(int i=front[x];i;i=e[i].nxt)
{
int v=e[i].v;
if(v!=son[x] && v!=fat[x])
dfs2(v,v);
}
}
inline void PushUp(int rt)
{
tree[rt]=min(tree[rt<<],tree[rt<<|]);
}
inline void PushDown(int rt)
{
if(lazy[rt])
{
tree[rt<<]=tree[rt<<|]=lazy[rt];
lazy[rt<<]=lazy[rt<<|]=lazy[rt];
lazy[rt]=;
}
}
void Build(int l,int r,int rt)
{
if(l==r)
{
tree[rt]=val[rank[l]];
return;
}
int mid=l+r>>;
Build(l,mid,rt<<);
Build(mid+,r,rt<<|);
PushUp(rt);
}
void Modify(int l,int r,int rt,int nowl,int nowr,int v)
{
if(nowl<=l && r<=nowr)
{
tree[rt]=lazy[rt]=v;
return;
}
PushDown(rt);
int mid=l+r>>;
if(nowl<=mid)Modify(l,mid,rt<<,nowl,nowr,v);
if(mid<nowr)Modify(mid+,r,rt<<|,nowl,nowr,v);
PushUp(rt);
}
int Query(int l,int r,int rt,int nowl,int nowr)
{
if(nowl<=l && r<=nowr)
return tree[rt];
PushDown(rt);
int mid=l+r>>,a=INF,b=INF;
if(nowl<=mid)a=Query(l,mid,rt<<,nowl,nowr);
if(mid<nowr)b=Query(mid+,r,rt<<|,nowl,nowr);
return min(a,b);
}
void FindFather()
{
for(int j=;j<=;j++)
for(int i=;i<=n;i++)
fa[i][j]=fa[fa[i][j-]][j-];
}
inline int Lca(int a,int b)
{
if(dep[a]<dep[b])swap(a,b);
int tmp=dep[a]-dep[b];
for(int i=;i>=;i--)
if(tmp&(<<i))
a=fa[a][i];
if(a==b)return a;
for(int i=;i>=;i--)
if(fa[a][i]!=fa[b][i])
{
a=fa[a][i];
b=fa[b][i];
}
return fa[a][];
}
inline void ModifyRoad(int x,int y,int v)
{
int f1=top[x],f2=top[y];
while(f1!=f2)
{
if(dep[f1]<dep[f2])swap(f1,f2),swap(x,y);
Modify(,n,,tid[f1],tid[x],v);
x=fat[f1];f1=top[x];
}
if(dep[x]>dep[y])swap(x,y);
Modify(,n,,tid[x],tid[y],v);
}
inline int QueryTree(int x)
{
if(x==rot)return tree[];
int lca=Lca(x,rot);
if(lca==x)
{
int tmp=dep[rot]-dep[x]-,v=rot;
for(int i=;i<=;i++)
if(tmp&(<<i))
v=fa[v][i];
return min(Query(,n,,,tid[v]-),Query(,n,,tid[v]+siz[v],n));
}
return Query(,n,,tid[x],tid[x]+siz[x]-);
}
int main()
{
scanf("%d%d",&n,&m);
int u,v,p,x;
for(int i=;i<=n-;i++)
{
u=qread();v=qread();
Insert(u,v);
Insert(v,u);
}
for(int i=;i<=n;i++)
val[i]=qread();
dfs1();dfs2(,);
Build(,n,);
FindFather();
scanf("%d",&rot);
for(int i=;i<=m;i++)
{
p=qread();
if(p==)rot=qread();
if(p==)
{
u=qread();v=qread();x=qread();
ModifyRoad(u,v,x);
}
if(p==)
{
x=qread();
printf("%d\n",QueryTree(x));
}
}
return ;
}

洛谷 P3979 遥远的国度的更多相关文章

  1. [洛谷P3979]遥远的国度

    题目大意:有一棵$n$个点的树,每个点有一个点权,有三种操作: $1\;x:$把根变成$x$ $2\;u\;v\;x:$把路径$u->v$上的点权改为$x$ $3\;x:$询问以$x$为根的子树 ...

  2. 洛谷P3979 遥远的国度 树链剖分+分类讨论

    题意:给出一棵树,这棵树每个点有权值,然后有3种操作.操作一:修改树根为rt,操作二:修改u到v路径上点权值为w,操作三:询问以rt为根x子树的最小权值. 解法:如果没有修改树根操作那么这题就是树链剖 ...

  3. 遥远的国度 (树链剖分换根),洛谷P3979

    析:显然,若没有换根操作,则为树链剖分板子题,但是这道题我们考虑换根操作 考虑这样一个性质:在一棵树上,两点的距离路径是唯一的!! 也就是说,我们在修改路径上的点权时,不必考虑根在哪里,直接利用模板修 ...

  4. 洛谷P1514 [NOIP2010提高组T4]引水入城

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

  5. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  6. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  7. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  8. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

  9. 洛谷P1710 地铁涨价

    P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交  讨论  题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...

随机推荐

  1. iview 表格随着更改刷新

    使用location.reload() 或者是 路由的 this.$router.go(0) 进行刷新的时候,是会出现一阵的空白区域的,因为是整个页面的刷新 ,所以比较缓慢,因此使用了provide/ ...

  2. 使用 SetParent 制作父子窗口的时候,如何设置子窗口的窗口样式以避免抢走父窗口的焦点

    原文:使用 SetParent 制作父子窗口的时候,如何设置子窗口的窗口样式以避免抢走父窗口的焦点 制作传统 Win32 程序以及 Windows Forms 程序的时候,一个用户看起来独立的窗口本就 ...

  3. Java Web 深入分析(12) JVM(2) 垃圾收集与内存分配

    前言 java的内存分配和垃圾回收往往是影响系统性能和并发能力的主要因素,虚拟机提供许多的参数就是为了根据不同环境和请教下进行调优,没有最好的调优也没有固定的调优.需要我们深入的去了解jvm的各个垃圾 ...

  4. Description Resource Path Location Type Unknown Unknown Unknown org.eclipse.core.internal.resources.Marker is not of a displayable type

    是访问限制报错. 方法一: 全局属性Project>preferences>java>Compiler>Errors/Warnings>把右侧的[Deprecated a ...

  5. iOS - app 进行安全加固

    研究了大半年逆向工程了,没在博客做记录,最近看到篇,跟自己的想法不谋而合,摘要下: 运行在越狱设备上的 iOS app,非常容易遭到破解分析,这里我列举一些可以加大破解难度的方法,希望有所帮助. 一些 ...

  6. Django流程图(精简版)

    网址: https://www.processon.com/view/link/5dddb0f8e4b074c442e5c68c

  7. vue和react之间的区别

    1.Vue和React之间的区别 相同点: Vue和其他框架一样,都有组件开发和虚拟dom 都支持props进行父子组件之间的数据通信 都支持数据驱动视图,不直接操作真实dom 都支持服务器端的 渲染 ...

  8. kafka环境安装及简单使用(单机版)

    一个分布式发布-订阅消息传递系统 特点: 高吞吐量.低延迟 使用场景(举例): 日志收集:用kafka收集各种服务产生的log,通过kafka以统一的接口服务的方式开放给各种consumer,如had ...

  9. python(time/random模块)

    一.Time模块 1.时间戳 时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数 最早出现的UNIX操作系统考虑到计算机 ...

  10. MySQL学习之基础篇09-事务

    我们在建表的时候通常会在最后声明引擎类型,这次我们就来看看存储引擎都有哪些: 举个例子: --------------------------- 银行转账: 张三想给李四转500元钱: 张三-500 ...