洛谷 P3979 遥远的国度
修改某条路径上的值以及询问子树的最小值都最树剖的基础操作,那么如何实现换根呢?
考虑一下三种情况:
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 遥远的国度的更多相关文章
- [洛谷P3979]遥远的国度
题目大意:有一棵$n$个点的树,每个点有一个点权,有三种操作: $1\;x:$把根变成$x$ $2\;u\;v\;x:$把路径$u->v$上的点权改为$x$ $3\;x:$询问以$x$为根的子树 ...
- 洛谷P3979 遥远的国度 树链剖分+分类讨论
题意:给出一棵树,这棵树每个点有权值,然后有3种操作.操作一:修改树根为rt,操作二:修改u到v路径上点权值为w,操作三:询问以rt为根x子树的最小权值. 解法:如果没有修改树根操作那么这题就是树链剖 ...
- 遥远的国度 (树链剖分换根),洛谷P3979
析:显然,若没有换根操作,则为树链剖分板子题,但是这道题我们考虑换根操作 考虑这样一个性质:在一棵树上,两点的距离路径是唯一的!! 也就是说,我们在修改路径上的点权时,不必考虑根在哪里,直接利用模板修 ...
- 洛谷P1514 [NOIP2010提高组T4]引水入城
P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城 ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
- 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP
题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...
- 洛谷P1710 地铁涨价
P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交 讨论 题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...
随机推荐
- 访问Harbor报502 Bad Gateway
Harbor启动都是多个容器的,首先查看一下是否有相关容器未启动 docker ps | grep harbor cae340214e57 goharbor/nginx-photon:v1.9.3 & ...
- 文件流CopyTo
- React Native 开发豆瓣评分(三)集成 Redux
什么是 redux redux 是一个用于管理 js 应用状态(state)的容器.比如组件 A 发生了变化,组件 B 要同时做出响应.常见的应用场景就是用户的登录退出操作:未登录状态,个人中心显示登 ...
- JAVA基础之XML相关
个人理解: 知晓XML与HTML的不同,知道其的自由性和约束的方式(规范)!数据按Schema约束写到XML里,然后通过dom4j解析出所有的元素,再用反射创建对象接着调出其所有的方法!!!特别要熟练 ...
- mongoose 警告信息 { useNewUrlParser: true } { useUnifiedTopology: true }
问题: 解决:
- 通过 Web Deploy 发布的配置
罩着别人的配置弄了一下午,死活认证通不过,后来好不容易试出来,备忘. 服务端:安装IIS,启动管理程序,安装Web Deploy, 建立网站,建立IIS用户,进网站的权限管理里面给IIS用户授权. V ...
- 七年开发浅谈Nginx负载均衡
一 特点 1.1 应用情况 Nginx做为一个强大的Web服务器软件,具有高性能.高并发性和低内存占用的特点.此外,其也能够提供强大的反向代理功能.俄罗斯大约有超过20%的虚拟主机采用Nginx作为反 ...
- python(函数封装)
一:Python 自定义函数 函数示意图如下: 1.使用函数的好处: 代码重用 保持一致性,易维护 可扩展性 2.函数定义 函数定义的简单规则: 函数代码块以def关键词开头 后接函数标识符名称和圆括 ...
- Java Decompiler反编译Jar文件
1.重新编译已经打包的Jar包,使用 Java Decompiler 打开需要重新编译的jar包,找到自己需要自己修改的Class文件 ,修改之后电子保存文件 ,保存的时候编译工具自动将class文件 ...
- springboot 使用常用注解
找到方法封装成json格式 @RestController = @Controller+@ResponseBody //一个组合注解,用于快捷配置启动类,springboot启动主入口 @Spring ...