题目

zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度。当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要zcwwzdjn完成任务后才能进入遥远的国度继续追杀。

问题是这样的:遥远的国度有n个城市,这些城市之间由一些路连接且这些城市构成了一颗树。这个国度有一个首都,我们可以把这个首都看做整棵树的根,但遥远的国度比较奇怪,首都是随时有可能变为另外一个城市的。遥远的国度的每个城市有一个防御值,有些时候RapiD会使得某两个城市之间的路径上的所有城市的防御值都变为某个值。RapiD想知道在某个时候,如果把首都看做整棵树的根的话,那么以某个城市为根的子树的所有城市的防御值最小是多少。由于RapiD无法解决这个问题,所以他拦住了zcwwzdjn希望他能帮忙。但zcwwzdjn还要追杀sb的zhx,所以这个重大的问题就被转交到了你的手上。

输入格式

第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为根的子树中的最小防御值。

输出格式

对于每个opt=3的操作,输出一行代表对应子树的最小点权值。

输入样例

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

输出样例

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。

题解

树剖,较为休闲

主要是换根问题,只影响询问结果

如果根与询问节点u的lca不为u,说明根在原树u的子树外,这样子换根后u的子树不变

如果lca为u,那么换根后只有根所在原树u的子树不在换根后u的子树内

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define ls (u << 1)
#define rs (u << 1 | 1)
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
return out * flag;
}
int h[maxn],ne = 2;
struct EDGE{int to,nxt;}ed[2 * maxn];
inline void build(int u,int v){
ed[ne] = (EDGE){v,h[u]}; h[u] = ne++;
ed[ne] = (EDGE){u,h[v]}; h[v] = ne++;
}
int n,m,val[maxn],capi;
int siz[maxn],dep[maxn],fa[maxn][18],top[maxn],son[maxn],id[maxn],Hash[maxn],cnt;
void dfs1(int u){
siz[u] = 1;
REP(i,17) fa[u][i] = fa[fa[u][i - 1]][i - 1];
Redge(u) if ((to = ed[k].to) != fa[u][0]){
dep[to] = dep[u] + 1; fa[to][0] = u;
dfs1(to);
siz[u] += siz[to];
if (!son[u] || siz[to] > siz[son[u]]) son[u] = to;
}
}
void dfs2(int u,int flag){
id[u] = ++cnt; Hash[cnt] = u;
top[u] = flag ? top[fa[u][0]] : u;
if (son[u]) dfs2(son[u],true);
Redge(u) if ((to = ed[k].to) != fa[u][0] && to != son[u])
dfs2(to,false);
}
int mn[4 * maxn],tag[4 * maxn];
void pd(int u){
if (tag[u]) mn[ls] = mn[rs] = tag[ls] = tag[rs] = tag[u],tag[u] = 0;
}
void build(int u,int l,int r){
if (l == r){
mn[u] = val[Hash[l]];
return;
}
int mid = l + r >> 1;
build(ls,l,mid);
build(rs,mid + 1,r);
mn[u] = min(mn[ls],mn[rs]);
}
void modify(int u,int l,int r,int L,int R,int v){
if (l >= L && r <= R){mn[u] = tag[u] = v; return;}
pd(u);
int mid = l + r >> 1;
if (mid >= L) modify(ls,l,mid,L,R,v);
if (mid < R) modify(rs,mid + 1,r,L,R,v);
mn[u] = min(mn[ls],mn[rs]);
}
int query(int u,int l,int r,int L,int R){
if (l >= L && r <= R) return mn[u];
pd(u);
int mid = l + r >> 1;
if (mid >= R) return query(ls,l,mid,L,R);
else if (mid < L) return query(rs,mid + 1,r,L,R);
else return min(query(ls,l,mid,L,R),query(rs,mid + 1,r,L,R));
}
int Lca(int u,int v){
if (dep[u] < dep[v]) swap(u,v);
if (dep[u] != dep[v]){
for (int i = 0,d = dep[u] - dep[v] - 1; (1 << i) <= d; i++)
if (d & (1 << i)) u = fa[u][i];
if (fa[u][0] == v) return u;
u = fa[u][0];
}
for (int i = 17; i >= 0; i--)
if (fa[u][i] != fa[v][i]) u = fa[u][i],v = fa[v][i];
return u;
}
void solve1(int u,int v,int x){
while (top[u] != top[v]){
if (dep[top[u]] < dep[top[v]]) swap(u,v);
modify(1,1,n,id[top[u]],id[u],x);
u = fa[top[u]][0];
}
if (dep[u] > dep[v]) swap(u,v);
modify(1,1,n,id[u],id[v],x);
}
void solve2(int u){
if (u == capi) {printf("%d\n",mn[1]); return;}
int lca = Lca(u,capi);
if (fa[lca][0] != u) printf("%d\n",query(1,1,n,id[u],id[u] + siz[u] - 1));
else {
int L = id[lca] - 1,R = id[lca] + siz[lca];
printf("%d\n",min(query(1,1,n,1,L),R <= n ? query(1,1,n,R,n) : INF));
}
}
int main(){
n = read(); m = read();
for (int i = 1; i < n; i++) build(read(),read());
for (int i = 1; i <= n; i++) val[i] = read();
dfs1(1); dfs2(1,0); build(1,1,n);
capi = read();
int opt,u,v;
while (m--){
opt = read();
if (opt == 1) capi = read();
else if (opt == 2){
u = read(); v = read();
solve1(u,v,read());
}else solve2(read());
}
return 0;
}

BZOJ3083 遥远的国度 【树剖】的更多相关文章

  1. P3979 遥远的国度 树剖

    P3979 遥远的国度 树剖 题面 需要想一下的树剖题,对于询问三需要处理换跟后的情况.我们以1为树根跑一遍剖分,对于换跟进行分类讨论,算出实际答案.讨论有三种情况: (以1为树根的树上) 跟在询问节 ...

  2. BZOJ3083: 遥远的国度(树链剖分)

    题意 $n$个节点的树,每个点有权值,支持三种操作 1. 换根 2.把$x$到$y$路径上节点权值变为$z$ 3.询问路径最小值 Sol 啥?你说这是TopTree的裸题?那你写去啊 很显然,如果没有 ...

  3. [日常摸鱼]bzoj3083遥远的国度-树链剖分

    一无聊就找树剖写 题意:一颗带点权的树,三种操作:1.换根 2.链赋值 3.查询子树最小值 如果没有换根的话直接就是裸的树剖了,对于换根的操作我们可以分类讨论. 1.如果查询的$x$就是根,那答案就是 ...

  4. BZOJ 3083: 遥远的国度 (树剖+线段树)

    传送门 解题思路 前两个操作都比较基础.对于第三个操作分类讨论一下,首先如果当前根不是要操作点的子树,那么就无影响,直接查询操作点的子树即可.第二种是当前根是操作点的子树,那就找到当前根到操作点这条链 ...

  5. 【BZOJ3083/3306】遥远的国度/树 树链剖分+线段树

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

  6. bzoj3083 遥远的国度 && bzoj3626 LCA (树链剖分)

    今早刷了两道树剖的题目,用时两小时十五分钟= = 树剖的题目代码量普遍120+ 其实打熟练之后是很容易调的,不熟练的话代码量大可能会因为某些小细节调很久 3083:裸树剖+"换根" ...

  7. BZOJ3083 遥远的国度(树链剖分+线段树)

    考虑暴力树剖.那么修改路径和查询子树最小值非常简单. 对于换根当然不能真的给他转一下,我们只记录当前根是哪个.对于查询,如果查询点不在当前根到原根的路径上,显然换根是对答案没有影响的:如果是当前根,答 ...

  8. BZOJ3083 遥远的国度 【树链剖分】

    BZOJ3083 遥远的国度 Description zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcw ...

  9. 【bzoj3083】遥远的国度 树链剖分+线段树

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

随机推荐

  1. windows系统下使用.net简单操作redis

    首先.net需要引入如下几个文件,在gitub或者官网应该是有的: 然后配置一下redis服务器: 端口: IP: 然后先启动  redis-server.exe: 出现如下效果表示成功 再启动:re ...

  2. codeforce Gym 100342J Triatrip (bitset)

    傻逼题,但是为什么别人的O(n^3)不会T?只是因为用了bitset优化... 附上一张bitset基本操作的表 #include<bits/stdc++.h> using namespa ...

  3. SQL Server 游标的应用

    ----------------SQL游标应用----------------- 今天由于业务需求,需要在存储过程中实现有一个表的主键去匹配在另一个表中作为外键所对应的数值 ,若在C#中则非常简单只需 ...

  4. ssh整合思想 Spring与Hibernate的整合 项目在服务器启动则自动创建数据库表

    Spring整合Hibernate Spring的Web项目中,web.xml文件会自动加载,以出现欢迎首页.也可以在这个文件中对Spring的配置文件进行监听,自启动配置文件, 以及之前Struts ...

  5. iOS 解决ipv6问题

    解决ipv6的方法有很多种,由于现在国内的网络运营商还在使用ipv4的网络环境,所以appstore应用不可能大范围去修改自己的服务器, 而且国内的云服务器几乎没有ipv6地址. 这里附上苹果开发平台 ...

  6. Some tricks

    一 . \(2^i >\sum_{0}^{i - 1}2^i\) 二. 当概率非常小时,且答案允许范围内的误差.如与正确答案不超过\(2^{-6}\)即可. 选取一个较小的值,然后取min即可. ...

  7. SAP HANA

    DROP PROCEDURE ""."ZCONCAT_EKKO_EBN"; CREATE PROCEDURE ""."ZCONCA ...

  8. Golang TCP转发到指定地址

    Golang TCP转发到指定地址 第二个版本,设置指定ip地址 代码 // tcpForward package main import ( "fmt" "net&qu ...

  9. C#基础-判断语句

    switch语句 Console.WriteLine("请输入月份"); string strInput = Console.ReadLine(); switch(strInput ...

  10. STM32CUBEMX入门学习笔记3:HAL库以及STM32CUBE相关资料

    微雪课堂:http://www.waveshare.net/study/article-629-1.html 之前的正点原子的例程资料 硬石科技stm32cube: 链接:https://pan.ba ...