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

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


总不能每次换根都对整个树剖一遍,因此我们要先以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_遥远的国度_树链剖分+线段树的更多相关文章

  1. B20J_2836_魔法树_树链剖分+线段树

    B20J_2836_魔法树_树链剖分+线段树 题意: 果树共有N个节点,其中节点0是根节点,每个节点u的父亲记为fa[u].初始时,这个果树的每个节点上都没有果子(即0个果子). Add u v d ...

  2. B20J_2243_[SDOI2011]染色_树链剖分+线段树

    B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...

  3. B20J_3231_[SDOI2014]旅行_树链剖分+线段树

    B20J_3231_[SDOI2014]旅行_树链剖分+线段树 题意: S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教. S国 ...

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

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

  5. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  6. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  7. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  8. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  9. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  10. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

随机推荐

  1. ORACLE之TO_DATE (转载)

    转自 http://www.cnblogs.com/anran_guojianjun/archive/2009/09/11/1564535.html 一.在使用Oracle的to_date函数来做日期 ...

  2. Web开发问题记录

    1.先说一个CSS的:CSS中带有中文(比如字体定义)的属性定义最好放在该选择器定义诸项的最后一条,为什么----编码格式问题. 2.其实自己也可以用自己写的DispatcherServlet+jsp ...

  3. Ocelot中文文档-流量控制

    感谢@catcherwong 的文章激励我最终写出了这个文档 Ocelot支持上游的请求限制,以便您的下游服务不会过载. 此功能是由GitHub上的@geffzhang添加! 非常感谢. 好了,为了让 ...

  4. Nodejs http-proxy代理实战应用

    var https = require('https'); var express = require('express'); var app = express() var http = requi ...

  5. [Java算法分析与设计]--单向链表(List)的实现和应用

    单向链表与顺序表的区别在于单向链表的底层数据结构是节点块,而顺序表的底层数据结构是数组.节点块中除了保存该节点对应的数据之外,还保存这下一个节点的对象地址.这样整个结构就像一条链子,称之为" ...

  6. Python 装饰器(Decorator)

    装饰器的语法为 @dec_name ,置于函数定义之前.如: import atexit @atexit.register def goodbye(): print('Goodbye!') print ...

  7. CSS学习笔记五:display,position区别

    最近常用css,经常在位置方面使用导display与position这两个属性,所以想要弄清楚它们之间的意思. 一.display 作用是规定元素应该生成的框的类型.意思是定义建立布局时元素生成的显示 ...

  8. nginx常用配置系列-静态资源处理

    接上篇,nginx处理静态资源的能力很强,后端服务器其实也可以处理静态资源,比如tomcat,但把非业务类的单一数据交给后端处理显然效率比较低,还有一种场景是多个站点公用一套资源集时,通过nginx可 ...

  9. PAT1088:Rational Arithmetic

    1088. Rational Arithmetic (20) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue F ...

  10. jsp页面日期格式不正确

    第一种: 如果是从数据库获取的时间(数据库中日期格式是乱的)可以在数据库取数据时   进行格式化   例如  ;TO_CHAR(SYSDATE,'YYYY-MM-DD') 第二种: 在数据库取出数据后 ...