BZOJ_3083_遥远的国度_树链剖分+线段树
BZOJ_3083_遥远的国度_树链剖分
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
1
2
3
4
总不能每次换根都对整个树剖一遍,因此我们要先以1为根进行树剖,然后对根的位置进行分类讨论。
假设询问的时x,根为root。
当root=x时直接输出整个树的最小值,这个必须要判而不能放到其他分类中。
当root在x的子树外时,由于x的子树没有变,相当于还是查询x的子树。
当root在x的子树内时,答案由两部分组成:
1.x子树外,这个对应树剖序上两段区间。
2.x子树内,需要刨去x到root路径上的点,我们对root不断跳重链,直到跳到x的儿子上,这个点的子树需要刨去,剩下的也是两段区间。
分类讨论完成后直接树剖+线段树即可。
注意权值可能爆int,需要用unsigned int
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 100050
#define ls p<<1
#define rs p<<1|1
#define inf ((1u<<31)+1)
typedef unsigned int un;
int head[N],to[N<<1],nxt[N<<1],n,cnt,m;
int son[N],fa[N],dep[N],siz[N],top[N],idx[N],root;
un t[N<<2],tag[N<<2],val[N],a[N];
inline void add(int u,int v) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
void dfs1(int x,int y) {
int i; fa[x]=y; dep[x]=dep[y]+1; siz[x]=1;
for(i=head[x];i;i=nxt[i]) {
if(to[i]!=y) {
dfs1(to[i],x);
siz[x]+=siz[to[i]];
if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
}
}
}
void dfs2(int x,int t) {
top[x]=t; idx[x]=++idx[0];
if(son[x]) dfs2(son[x],t);
int i;
for(i=head[x];i;i=nxt[i]) {
if(to[i]!=fa[x]&&to[i]!=son[x]) dfs2(to[i],to[i]);
}
}
void build(int l,int r,int p) {
if(l==r) {
t[p]=a[l]; return ;
}
int mid=(l+r)>>1;
build(l,mid,ls); build(mid+1,r,rs);
t[p]=min(t[ls],t[rs]);
}
inline void pushdown(int p) {
if(tag[p]) {
t[ls]=tag[ls]=tag[p];
t[rs]=tag[rs]=tag[p];
tag[p]=0;
}
}
void update(int l,int r,int x,int y,un v,int p) {
if(x<=l&&y>=r) {
t[p]=v; tag[p]=v; return ;
}
pushdown(p);
int mid=(l+r)>>1;
if(x<=mid) update(l,mid,x,y,v,ls);
if(y>mid) update(mid+1,r,x,y,v,rs);
t[p]=min(t[ls],t[rs]);
}
un qmin(int l,int r,int x,int y,int p) {
if(x<=l&&y>=r) return t[p];
pushdown(p);
int mid=(l+r)>>1;
un re=inf;
if(x<=mid) re=min(re,qmin(l,mid,x,y,ls));
if(y>mid) re=min(re,qmin(mid+1,r,x,y,rs));
return re;
}
un solve(int x,int y) {
un re=inf;
if(idx[x]<=idx[y]-1) re=min(re,qmin(1,n,idx[x],idx[y]-1,1));
if(idx[y]+siz[y]<=idx[x]+siz[x]-1) re=min(re,qmin(1,n,idx[y]+siz[y],idx[x]+siz[x]-1,1));
return re;
}
int main() {
scanf("%d%d",&n,&m);
int i,x,y,opt;
un z;
for(i=1;i<n;i++) {
scanf("%d%d",&x,&y);
add(x,y); add(y,x);
}
for(i=1;i<=n;i++) scanf("%u",&i[val]);
scanf("%d",&root);
dfs1(1,0);
dfs2(1,1);
for(i=1;i<=n;i++) a[idx[i]]=val[i];
build(1,n,1);
while(m--) {
scanf("%d%d",&opt,&x);
if(opt==1) {
root=x;
}else if(opt==2) {
scanf("%d%u",&y,&z);
while(top[x]!=top[y]) {
if(dep[top[x]]>dep[top[y]]) swap(x,y);
update(1,n,idx[top[y]],idx[y],z,1);
y=fa[top[y]];
}
if(dep[x]<dep[y]) swap(x,y);
update(1,n,idx[y],idx[x],z,1);
}else {
if(root==x) {
printf("%d\n",t[1]);
}else if(idx[root]<idx[x]||idx[root]>idx[x]+siz[x]-1) {
printf("%u\n",qmin(1,n,idx[x],idx[x]+siz[x]-1,1));
}else {
un re=inf;
if(1<=idx[x]-1) re=min(re,qmin(1,n,1,idx[x]-1,1));
if(idx[x]+siz[x]<=n) re=min(re,qmin(1,n,idx[x]+siz[x],n,1));
int y=root;
if(fa[y]==x) {
re=min(re,solve(x,y));
}else {
if(top[y]==top[x]) {
re=min(re,solve(x,son[x]));
}else {
while(fa[y]!=x) {
y=fa[y];
if(fa[y]==x) break;
if(top[x]==top[y]) break;
y=top[y];
}
while(fa[y]!=x) y=fa[y];
re=min(re,solve(x,y));
}
}
printf("%u\n",re);
}
}
}
}
BZOJ_3083_遥远的国度_树链剖分+线段树的更多相关文章
- B20J_2836_魔法树_树链剖分+线段树
B20J_2836_魔法树_树链剖分+线段树 题意: 果树共有N个节点,其中节点0是根节点,每个节点u的父亲记为fa[u].初始时,这个果树的每个节点上都没有果子(即0个果子). Add u v d ...
- B20J_2243_[SDOI2011]染色_树链剖分+线段树
B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...
- B20J_3231_[SDOI2014]旅行_树链剖分+线段树
B20J_3231_[SDOI2014]旅行_树链剖分+线段树 题意: S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教. S国 ...
- 【bzoj3083】遥远的国度 树链剖分+线段树
题目描述 描述zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要zcwwzdjn ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
随机推荐
- c程序的编译
linux系统下采用gcc进行编译,而在aix系统下采用xlc 进行编译. 附上aix安装xlc地址:https://www.ibm.com/developerworks/cn/aix/library ...
- HTML DOM 实例
DOMAnchor 对象 更改一个链接的文本.URL 以及 target 使用 focus() 和 blur() 向超链接添加快捷键 Document 对象 使用 document.write() 向 ...
- 通过jQuery源码学习javascript(三)
承接上两篇继续写下去.我尽量把我明白的地方给大家说清楚.有些大家的提问我也有点搞不明白,如果有人能解答,再好不过了 疑问 第一篇中有位博友提出了以下的问题,我也不太明白,如果有明白的,能否告知一.二 ...
- pslq常用操作
1,登录后默认自动选中My Objects 默认情况下,PLSQL Developer登录后,Brower里会选择All objects,如果你登录的用户是dba,要展开tables目录,正常情况都 ...
- Jmeter 性能测试术语
1.5 术语及缩写词 测试时间:一轮测试从开始到结束所使用的时间 并发线程数:测试时同时访问被测系统的线程数.注意,由于测试过程中,每个线程都是以尽可能快的速度发请求,与实际用户的使用有极大差别,所以 ...
- MySql foreach属性
foreach属性 属性 描述 item 循环体中的具体对象.支持属性的点路径访问,如item.age,item.info.details.具体说明:在list和数组中是其中的对象,在map中是val ...
- java深入浅出之数据结构
1.整形数据 byte.short.int.long,分别是1248个字节的存储量,取值范围也是依次增大的,其中int是正负21亿多: long a = 1111222233334444L:记住后面要 ...
- Ext Js Sencha Cmd 命令 打包charts
先进入charts包的目录下 cd D:\开发文档API\ext--gpl\packages\charts 在执行打包命令 sencha package build
- TensorFlow图像处理API
TensorFlow提供了一些常用的图像处理接口,可以让我们方便的对图像数据进行操作,以下首先给出一段显示原始图片的代码,然后在此基础上,实践TensorFlow的不同API. 显示原始图片 impo ...
- SQL转化为MapReduce的过程
转载:http://www.cnblogs.com/yaojingang/p/5446310.html 在了解了MapReduce实现SQL基本操作之后,我们来看看Hive是如何将SQL转化为MapR ...