题目描述

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

考虑一下三种情况:

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. Java对象深拷贝浅拷贝总结

    目录 深拷贝 1. 手动new 2. clone方法 3. java自带序列化 4. json序列化 性能测试 深拷贝总结 浅拷贝 1. spring BeanUtils(Apache BeanUti ...

  2. python 获取mysql数据库列表以及用户权限

    一.需求分析 需要统计出当前数据库的所有数据库名,以及每个用户的授权信息. 获取所有数据库 在mysql里面,使用命令: show databases 就可以获取所有数据库了 获取所有用户 执行命令: ...

  3. Different Subsets For All Tuples CodeForces - 660E (组合计数)

    大意: 定义$f(a)$表示序列$a$本质不同子序列个数. 给定$n,m$, 求所有长$n$元素范围$[1,m]$的序列的$f$值之和. 显然长度相同的子序列贡献是相同的. 不考虑空串, 假设长$x$ ...

  4. golang ---获取IP Address

    package main import ( "fmt" "log" "os/exec" "regexp" ) func ...

  5. Springboot 结合百度IORC实现自定义模板图片识别

    前言: 首先呢,最近再公司的项目当中遇到这样的一个问题,就是需要识别图片,提取图片当中的关键语句,而且识别的语句当然是人家手写体识别,翻来覆去一想,最终还是决定使用百度的OCR帮助我解决这一项需求 话 ...

  6. java之struts2的ThreadLocal和ActionContext

    在之前的学习中,我们知道struts2可以将表单中的数据自动设置到处理类的属性上,还有类型转换等其他功能.那么struts2是怎样做这件事情的呢? struts2完成这些功能是通过拦截器来完成的,并且 ...

  7. centos 7 安装nginx并启动(笔记)

    参考 https://www.cnblogs.com/liujuncm5/p/6713784.html Nginx 是 C语言 开发 一. gcc 安装安装 nginx 需要先将官网下载的源码进行编译 ...

  8. 谷歌浏览器解决ajax跨域问题

    在用mui和H5+做混合开发,会利用HBuildx去真机调试,可真机调试总有问题所在,懂得人自然懂,而我们直接打开页面显示的只有一个静态的页面,是获取不到数据的在这里我想说的不是代码中利用jsonp, ...

  9. 阿里云ssl协议发布qq邮件

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx. ...

  10. 【雅思】【绿宝书错词本】List25~36

    List 25 ❤arable a.可耕作的 n.耕地 ❤congested a.拥挤不堪的:充塞的 ❤split v.(使)分裂,分离:(被)撕裂:裂开:劈开:分担,分享n.裂口:分化 ,分裂 ❤n ...