BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]
3083: 遥远的国度
Time Limit: 10 Sec Memory Limit: 1280 MB
Submit: 3127 Solved: 795
[Submit][Status][Discuss]
Description
描述
zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度。当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要zcwwzdjn完成任务后才能进入遥远的国度继续追杀。
问题是这样的:遥远的国度有n个城市,这些城市之间由一些路连接且这些城市构成了一颗树。这个国度有一个首都,我们可以把这个首都看做整棵树的根,但遥远的国度比较奇怪,首都是随时有可能变为另外一个城市的。遥远的国度的每个城市有一个防御值,有些时候RapiD会使得某两个城市之间的路径上的所有城市的防御值都变为某个值。RapiD想知道在某个时候,如果把首都看做整棵树的根的话,那么以某个城市为根的子树的所有城市的防御值最小是多少。由于RapiD无法解决这个问题,所以他拦住了zcwwzdjn希望他能帮忙。但zcwwzdjn还要追杀sb的zhx,所以这个重大的问题就被转交到了你的手上。
Input
第1行两个整数n m,代表城市个数和操作数。
第2行至第n行,每行两个整数 u v,代表城市u和城市v之间有一条路。
第n+1行,有n个整数,代表所有点的初始防御值。
第n+2行一个整数 id,代表初始的首都为id。
第n+3行至第n+m+2行,首先有一个整数opt,如果opt=1,接下来有一个整数id,代表把首都修改为id;如果opt=2,接下来有三个整数p1 p2 v,代表将p1 p2路径上的所有城市的防御值修改为v;如果opt=3,接下来有一个整数 id,代表询问以城市id为根的子树中的最小防御值。
Output
对于每个opt=3的操作,输出一行代表对应子树的最小点权值。
Sample Input
1 2
1 3
1 2 3
1
3 1
2 1 1 6
3 1
2 2 2 5
3 1
2 3 3 4
3 1
Sample Output
2
3
4
提示
对于20%的数据,n<=1000 m<=1000。
对于另外10%的数据,n<=100000,m<=100000,保证修改为单点修改。
对于另外10%的数据,n<=100000,m<=100000,保证树为一条链。
对于另外10%的数据,n<=100000,m<=100000,没有修改首都的操作。
对于100%的数据,n<=100000,m<=100000,0<所有权值<=2^31。
HINT
Source
这么快A掉好高兴
没有换根,不就是dfs剖分裸题嘛?
加上换根后,发现换根后树形态不变,两点之间路径不变,并且有些子树也没变
对于询问分类讨论
x==rt 查询[1,n](注意这里要特判,一开始没有处理)
x在rt的子树内,子树没有变
x不在rt到原根的链上,子树没有变
x在rt到原根的链上,(即x=lca(x,rt)),发现现在x的子树就是整棵树减去x往rt方向向下那个节点的子树,于是倍增求那个点然后整个dfs序就是分成两段了啊
dfs的问题:没有必要出栈单独,最后一种情况就是[1,L[v]-1]和[R[v]+1,n]
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define lc o<<1
#define rc o<<1|1
#define m ((l+r)>>1)
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
const int N=1e5+,INF=;
typedef long long ll;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,Q,rt,w[N],fw[N],op,a,b,v;
struct edge{
int v,ne;
}e[N<<];
int cnt,h[N];
inline void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
}
int deep[N],fa[N][],tid[N],top[N],tot,size[N],mx[N];
int L[N],R[N];
void dfs(int u){
size[u]=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(v==fa[u][]) continue;
fa[v][]=u;deep[v]=deep[u]+;
dfs(v);
size[u]+=size[v];
if(size[v]>size[mx[u]]) mx[u]=v;
}
}
void dfs(int u,int anc){
if(!u) return;
tid[u]=L[u]=++tot;
top[u]=anc;
for(int j=;(<<j)<=deep[u];j++)
fa[u][j]=fa[fa[u][j-]][j-];
dfs(mx[u],anc);
for(int i=h[u];i;i=e[i].ne)
if(e[i].v!=fa[u][]&&e[i].v!=mx[u]) dfs(e[i].v,e[i].v);
R[u]=tot;
}
int lca(int x,int y){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]]) swap(x,y);
x=fa[top[x]][];
}
if(deep[x]>deep[y]) swap(x,y);
return x;
} struct node{
int mn,set;
}t[N<<];
inline void merge(int o){
t[o].mn=min(t[lc].mn,t[rc].mn);
}
inline void paint(int o,int v){
t[o].mn=t[o].set=v;
}
inline void pushDown(int o){
if(t[o].set){
paint(lc,t[o].set);
paint(rc,t[o].set);
t[o].set=;
}
}
void build(int o,int l,int r){
if(l==r) paint(o,w[l]);
else{
build(lson);
build(rson);
merge(o);
}
}
void segCha(int o,int l,int r,int ql,int qr,int v){
if(ql<=l&&r<=qr) paint(o,v);
else{
pushDown(o);
if(ql<=m) segCha(lson,ql,qr,v);
if(m<qr) segCha(rson,ql,qr,v);
merge(o);
}
}
int segQue(int o,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr) return t[o].mn;
else{
pushDown(o);
int mn=INF;
if(ql<=m) mn=min(mn,segQue(lson,ql,qr));
if(m<qr) mn=min(mn,segQue(rson,ql,qr));
return mn;
}
} void change(int x,int y,int v){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]]) swap(x,y);
segCha(,,n,tid[top[x]],tid[x],v);
x=fa[top[x]][];
}
if(tid[x]>tid[y]) swap(x,y);
segCha(,,n,tid[x],tid[y],v);
} int jump2anc(int x,int d){
int bin=deep[x]-d;
for(int j=;j<=;j++)
if((<<j)&bin) x=fa[x][j];
return x;
}
int query(int x){
if(x==rt) return segQue(,,n,,n);
else if(L[rt]<=tid[x]&&tid[x]<=R[rt]) return segQue(,,n,L[x],R[x]);
else{
int p=lca(x,rt);
if(x!=p) return segQue(,,n,L[x],R[x]);
else{
int v=jump2anc(rt,deep[x]+);
return min(segQue(,,n,R[v]+,n),segQue(,,n,,L[v]-));
}
}
} int main(){
//freopen("in.txt","r",stdin);
n=read();Q=read();
for(int i=;i<=n-;i++) a=read(),b=read(),ins(a,b);
for(int i=;i<=n;i++) fw[i]=read();
rt=read();
dfs(rt);dfs(rt,rt);
for(int i=;i<=n;i++) w[tid[i]]=fw[i];//,printf("hi %d %d %d %d %d\n",i,tid[i],w[tid[i]],L[i],R[i]);
build(,,n); while(Q--){
op=read();
if(op==) rt=read();
else if(op==) printf("%d\n",query(read()));
else{
a=read();b=read();v=read();
change(a,b,v);
}
}
}
BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]的更多相关文章
- BZOJ 3083: 遥远的国度(树链剖分+DFS序)
可以很显而易见的看出,修改就是树链剖分,而询问就是在dfs出的线段树里查询最小值,但由于这道题会修改根节点,所以在查询的时候需判断x是否为root的祖先,如果不是就直接做,是的话应该查询从1-st[y ...
- BZOJ 3083 遥远的国度 树链剖分
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 797 Solved: 181[Submit][Status] Descrip ...
- BZOJ 3083 遥远的国度(树链剖分+LCA)
Description 描述zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要z ...
- BZOJ 3083 遥远的国度 树链剖分+线段树
有换根的树链剖分的裸题. 在换根的时候注意讨论. 注意数据范围要开unsigned int或longlong #include<iostream> #include<cstdio&g ...
- bzoj 3083 遥远的国度 —— 树链剖分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 换根后路径还是不变,子树分类讨论一下,树剖后线段树维护即可. 代码如下: #inclu ...
- bzoj 3083 遥远的国度——树链剖分+线段树维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 int 的范围是 2^31 - 1 ,所以权值是不是爆 int 了…… O( nlog ...
- BZOJ 3083 遥远的国度 树链剖分+脑子
唉..又调了半天QWQ..为何读入挂了.....莫非读入是反着的????据ywy学长所言如是...OvO震惊 这啥骚题啊...还要换根...不过清明讲过...(然鹅我现在才做... 先随便选个点(比如 ...
- [BZOJ - 2819] Nim 【树链剖分 / DFS序】
题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...
- 树链剖分&dfs序
树上问题 很多处理区间的问题(像是RMQ,区间修改).可以用线段树,树状数组,ST表这些数据结构来维护.但是如果将这些问题挪到了树上,就不能直接用这些数据结构来处理了.这时就用到了dfs序和树链剖分. ...
随机推荐
- 【AutoMapper官方文档】DTO与Domin Model相互转换(上)
写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...
- Web Api 入门实战 (快速入门+工具使用+不依赖IIS)
平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html 屁话我也就不多说了,什么简介的也省了,直接简单概括+demo ...
- svn 常用命令总结
svn 命令篇 svn pget svn:ignore // 查看忽略项 svn commit -m "提交说明" // 提交修改 svn up(update) // 获取最新版本 ...
- 【原创经验分享】WCF之消息队列
最近都在鼓捣这个WCF,因为看到说WCF比WebService功能要强大许多,另外也看了一些公司的招聘信息,貌似一些中.高级的程序员招聘,都有提及到WCF这一块,所以,自己也关心关心一下,虽然目前工作 ...
- springMVC初探--环境搭建和第一个HelloWorld简单项目
注:此篇为学习springMVC时,做的笔记整理. MVC框架要做哪些事情? a,将url映射到java类,或者java类的方法上 b,封装用户提交的数据 c,处理请求->调用相关的业务处理—& ...
- 一个IT人的成长路
毕业四年多了,来深圳三年多了,经历了刚毕业的懵懂少年,成长为现在的成熟稳重青年.职场上,从刚毕业的小白,成长为现在可以成熟应对各种事情的老司机.经历过从初级研发工程师,到中级研发工程师,到高级研发工程 ...
- 【夯实PHP基础】PHP常用类和函数总结
本文地址 代码提纲: 1. 字符串处理类及函数 2. 数组处理类及函数 3 .web处理类及函数 将常用的PHP的类和函数总结到这里,主要是 自己用过的,比较有感觉. 1. [字符串处理] 1)[ut ...
- 【从零开始学BPM,Day3】自定义表单开发
[课程主题] 主题:5天,一起从零开始学习BPM [课程形式] 1.为期5天的短任务学习 2.每天观看一个视频,视频学习时间自由安排. [第三天课程] 1.课程概要 Step 1 软件下载:H3 BP ...
- Hadoop 2.x 生态系统及技术架构图
一.负责收集数据的工具:Sqoop(关系型数据导入Hadoop)Flume(日志数据导入Hadoop,支持数据源广泛)Kafka(支持数据源有限,但吞吐大) 二.负责存储数据的工具:HBaseMong ...
- CSS垂直居中总结
工作中遇到垂直居中问题,特此总结了一下几种方式与大家分享.本文讨论的垂直居中仅支持IE8+ 1.使用绝对定位垂直居中 <div class="container"> & ...