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

3 7
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

1
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

zhonghaoxi提供


这么快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]的更多相关文章

  1. BZOJ 3083: 遥远的国度(树链剖分+DFS序)

    可以很显而易见的看出,修改就是树链剖分,而询问就是在dfs出的线段树里查询最小值,但由于这道题会修改根节点,所以在查询的时候需判断x是否为root的祖先,如果不是就直接做,是的话应该查询从1-st[y ...

  2. BZOJ 3083 遥远的国度 树链剖分

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 797  Solved: 181[Submit][Status] Descrip ...

  3. BZOJ 3083 遥远的国度(树链剖分+LCA)

    Description 描述zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要z ...

  4. BZOJ 3083 遥远的国度 树链剖分+线段树

    有换根的树链剖分的裸题. 在换根的时候注意讨论. 注意数据范围要开unsigned int或longlong #include<iostream> #include<cstdio&g ...

  5. bzoj 3083 遥远的国度 —— 树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 换根后路径还是不变,子树分类讨论一下,树剖后线段树维护即可. 代码如下: #inclu ...

  6. bzoj 3083 遥远的国度——树链剖分+线段树维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 int 的范围是 2^31 - 1 ,所以权值是不是爆 int 了…… O( nlog ...

  7. BZOJ 3083 遥远的国度 树链剖分+脑子

    唉..又调了半天QWQ..为何读入挂了.....莫非读入是反着的????据ywy学长所言如是...OvO震惊 这啥骚题啊...还要换根...不过清明讲过...(然鹅我现在才做... 先随便选个点(比如 ...

  8. [BZOJ - 2819] Nim 【树链剖分 / DFS序】

    题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...

  9. 树链剖分&dfs序

    树上问题 很多处理区间的问题(像是RMQ,区间修改).可以用线段树,树状数组,ST表这些数据结构来维护.但是如果将这些问题挪到了树上,就不能直接用这些数据结构来处理了.这时就用到了dfs序和树链剖分. ...

随机推荐

  1. .NET跨平台之旅:将示例站点升级至 ASP.NET Core 1.1

    微软今天在 Connect(); // 2016 上发布了 .NET Core 1.1 ,ASP.NET Core 1.1 以及 Entity Framework Core 1.1.紧跟这次发布,我们 ...

  2. 【WCF】自定义错误处理(IErrorHandler接口的用法)

    当被调用的服务操作发生异常时,可以直接把异常的原始内容传回给客户端.在WCF中,服务器传回客户端的异常,通常会使用 FaultException,该异常由这么几个东东组成: 1.Action:在服务调 ...

  3. 通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流程[下]:管道是如何构建起来的?

    在<中篇>中,我们对管道的构成以及它对请求的处理流程进行了详细介绍,接下来我们需要了解的是这样一个管道是如何被构建起来的.总的来说,管道由一个服务器和一个HttpApplication构成 ...

  4. 带你实现开发者头条APP(三) 首页实现

    title: 带你实现开发者头条APP(三) 首页实现 tags: 轮播广告,ViewPager切换,圆形图片 grammar_cjkRuby: true --- 一.前言 今天实现开发者头条APP的 ...

  5. Hadoop学习之旅二:HDFS

    本文基于Hadoop1.X 概述 分布式文件系统主要用来解决如下几个问题: 读写大文件 加速运算 对于某些体积巨大的文件,比如其大小超过了计算机文件系统所能存放的最大限制或者是其大小甚至超过了计算机整 ...

  6. jQuery radio的取值与赋值

    取值: $("input[name='radioName']:checked").val(); 赋值: $("input[name='radioName'][value= ...

  7. Autofac 的点滴

    泛型类型的注册和使用 public interface IRepository<T> where T:class { } public interface ISchoolDetailRep ...

  8. linux常用命令(1)cd命令

    1 命令格式:cd [目录名]2 命令功能切换当前目录至dirName3 常用范例3.1 进入系统根目录cd /3.2 进入上级目录cd ..   或者 cd ..//3.3 进入当前用户主目录当前用 ...

  9. DDD中的Unitwork与DomainEvent如何相容?(续)

    上篇中说到了面临的问题(传送门:DDD设计中的Unitwork与DomainEvent如何相容?),和当时实现的一个解决方案.在实际使用了几天后,有了新的思路,和@trunks 兄提出的观点类似.下面 ...

  10. 判断一个对象是jQuery对象还是DOM对象

    今天调试一段代码的时候,看到其中一个变量,想知道它到底是jquery对象还是dom对象. 虽然直接console出这个对象,看它的内部可以判断出来.但是我想有没有什么更方便的方法呢. 后来我想到了一个 ...