题目描述

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

考虑一下三种情况:

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. 「CTS2019」珍珠

    「CTS2019」珍珠 解题思路 看了好多博客才会,问题即要求有多少种方案满足数量为奇数的变量数 \(\leq n-2m\).考虑容斥,令 \(F(k)\) 为恰好有 \(n\) 个变量数量为奇数的方 ...

  2. C# vb实现浮雕特效滤镜效果

    在.net中,如何简单快捷地实现Photoshop滤镜组中的浮雕效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一步 ...

  3. 生物网络,RNA 与疾病关联分析

    题目: 大数据时代下基于网络算法和机器学习的非编码RNA 相关预测研究摘要:最近越来越多的生物实验表明非编码RNA 具有非常重要的生物学功能,参与细胞中的多项重要生命活动,调控许多基本且重要的生物过程 ...

  4. 虚拟机与宿主机可以互相ping通,但是外网不能

    http://rickcheung.blog.51cto.com/913220/354429 1.CentOS 修改DNS 修改对应网卡的DNS的配置文件 # vi /etc/resolv.conf  ...

  5. MySQL连接使用

    在mysql查询中,我们会通过排序,分组等在一张表中读取数据,这是比较简单的,但是在真正的应用中经常需要从多个数据表中读取数据.下面就为大家介绍这种方式,链接查询join. INNER JOIN(内连 ...

  6. 行内块inline-block元素之间出现空白间隙原因及解决办法

    首先,来看下具体的问题,下面是用inline-block布局实现的两边固定宽度,中间自适应的html代码: 1 2 3 4 5 6 7 8 9 <section class="layo ...

  7. pre-departure preparation-to chengdu or shenzhen

    编辑本文 (一)思想要点 1.行动改变自己,做自己的救世主. 2.成为一个技术大拿. 3.当生活吊打了你,不用悲伤,尽快反击(力所能及的做事),不要停歇,因为不能再给生活喘息的机会. 4.遇到什么问题 ...

  8. 【微信小程序】——wxss引用外部CSS文件及iconfont,图文教程

    小程序引入外部文件的方式是:@import “/.wxss”; 小程序的wxss文件font-face的url不接受http地址作为参数,可以接受base64,因此可以先将字体文件下载后,转换为bas ...

  9. 【转】关于TCP/IP,必须知道的十个知识点

    本文整理了一些TCP/IP协议簇中需要必知必会的十大问题,既是面试高频问题,又是程序员必备基础素养. 一.TCP/IP模型 TCP/IP协议模型(Transmission Control Protoc ...

  10. tengine编译安装及nginx高并发内核参数优化

    Tengine Tengine介绍 Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性. Tengine的性能和稳定性已经在大型的 ...