记最开始的根为root,换根之后,对于当前的根rtnow和询问子树U而言,

①rtnow==U,询问整棵树

②fa[rtnow]==U,询问除了rtnow所在子树以外的整棵树

③rtnow在U的子树里,且距离大于1,询问除了rtnow的除了其祖先是U的儿子的祖先的子树以外的整棵树

④rtnow不在U的子树里,询问U的子树

对于③,在树链上跳跳就好了,也可以暴力,复杂度无法保证。

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define N 100001
#define INF 2147483647
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
int v[N<<1],en,next[N<<1],first[N];
void AddEdge(int U,int V)
{
v[++en]=V;
next[en]=first[U];
first[U]=en;
}
int n,m,root,a[N];
int Ls[N],Rs[N],top[N],siz[N],fa[N],dep[N],tot,son[N],rtnow,Map[N];
void dfs(int U)
{
siz[U]=1;
for(int i=first[U];i;i=next[i])
if(v[i]!=fa[U])
{
fa[v[i]]=U;
dep[v[i]]=dep[U]+1;
dfs(v[i]);
siz[U]+=siz[v[i]];
if(siz[v[i]]>siz[son[U]])
son[U]=v[i];
}
}
void dfs2(int U)
{
Ls[U]=++tot;
Map[tot]=U;
if(son[U])
{
top[son[U]]=top[U];
dfs2(son[U]);
}
for(int i=first[U];i;i=next[i])
if(v[i]!=fa[U]&&v[i]!=son[U])
{
top[v[i]]=v[i];
dfs2(v[i]);
}
Rs[U]=tot;
}
int minv[N<<2],cov[N<<2];
void pushdown(int rt)
{
if(cov[rt])
{
cov[rt<<1]=cov[rt<<1|1]=minv[rt<<1]=minv[rt<<1|1]=cov[rt];
cov[rt]=0;
}
}
void update(int ql,int qr,int v,int rt,int l,int r)
{
if(ql<=l&&r<=qr)
{
cov[rt]=minv[rt]=v;
return;
}
pushdown(rt);
int m=(l+r>>1);
if(ql<=m) update(ql,qr,v,lson);
if(m<qr) update(ql,qr,v,rson);
minv[rt]=min(minv[rt<<1],minv[rt<<1|1]);
}
int query(int ql,int qr,int rt,int l,int r)
{
if(ql<=l&&r<=qr) return minv[rt];
pushdown(rt);
int m=(l+r>>1),res=INF;
if(ql<=m) res=min(res,query(ql,qr,lson));
if(m<qr) res=min(res,query(ql,qr,rson));
return res;
}
void Update(int U,int V,int W)
{
int f1=top[U],f2=top[V],res=INF;
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(f1,f2);
swap(U,V);
}
update(Ls[f1],Ls[U],W,1,1,n);
U=fa[U];
f1=top[U];
}
if(dep[U]>dep[V])
swap(U,V);
update(Ls[U],Ls[V],W,1,1,n);
}
int main()
{
// freopen("bzoj3083.in","r",stdin);
int A,B,C,op;
scanf("%d%d",&n,&m);
for(int i=1;i<n;++i)
{
scanf("%d%d",&A,&B);
AddEdge(A,B);
AddEdge(B,A);
}
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
scanf("%d",&root);
top[root]=root;
dfs(root);
dfs2(root);
for(int i=1;i<=n;++i) update(Ls[i],Ls[i],a[i],1,1,n);
for(;m;--m)
{
scanf("%d",&op);
if(op==1) scanf("%d",&rtnow);
else if(op==2)
{
scanf("%d%d%d",&A,&B,&C);
Update(A,B,C);
}
else
{
scanf("%d",&A);
if(A==rtnow)
printf("%d\n",query(1,n,1,1,n));
else if(fa[rtnow]==A)
printf("%d\n",min(query(1,Ls[rtnow]-1,1,1,n),Rs[rtnow]==n?INF:query(Rs[rtnow]+1,n,1,1,n)));
else if(Ls[rtnow]>=Ls[A]&&Ls[rtnow]<=Rs[A])
{
int U=rtnow;
while(fa[top[U]]!=A&&top[U]!=top[A])
U=fa[top[U]];
if(fa[top[U]]!=A)
U=Map[Ls[A]+1];
else
U=top[U];
printf("%d\n",min(query(1,Ls[U]-1,1,1,n),Rs[U]==n?INF:query(Rs[U]+1,n,1,1,n)));
}
else
printf("%d\n",query(Ls[A],Rs[A],1,1,n));
}
}
return 0;
}

【树链剖分】【线段树】bzoj3083 遥远的国度的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  9. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  10. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

随机推荐

  1. codeforces 1015E1&&E2

    E1. Stars Drawing (Easy Edition) time limit per test 3 seconds memory limit per test 256 megabytes i ...

  2. php 上传csv文件

    php fgetcsv()函数 定义和用法 fgetcsv() 函数从文件指针中读入一行并解析 CSV 字段. 与 fgets() 类似,不同的是 fgetcsv() 解析读入的行并找出 CSV 格式 ...

  3. JavaScript中Array(数组)的属性和方法(转)

    数组有四种定义的方式 使用构造函数:var a = new Array();var b = new Array(8);var c = new Array("first", &quo ...

  4. 【AtCoder】ARC082 F - Sandglass

    [链接]F - Sandglass [题意]给定沙漏A和B,分别装着a和X-a的沙子,开始时A在上B在下,每秒漏1,漏完不再漏.给定n,有n个时刻ai沙漏倒转.给定m个询问,每次询问给定初值a和时刻t ...

  5. windows注册表存储位置

    win7/8/10 通常情况: HKEY_LOCAL_MACHINE \SYSTEM : \system32\config\system HKEY_LOCAL_MACHINE \SAM : \syst ...

  6. [Leetcode Week6]Linked List Cycle

    Linked List Cycle 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/linked-list-cycle/description/ Des ...

  7. Linux IO 同步/异步 阻塞/非阻塞

    同步IO:导致请求进程阻塞,直到IO操作完成: 是内核通知我们何时进行启动IO操作,而实际的IO操作需要当前进程本身阻塞完成: 包括:阻塞式IO模型,非阻塞式IO模型,IO复用模型,信号驱动式IO模型 ...

  8. 函数:module_put ( )【转】

    转自:http://book.2cto.com/201307/27049.html 文件包含: #include <linux/module.h> 函数定义: 函数在内核源码中的位置:li ...

  9. mvn常用的构建命令

    mvn -v 查看maven版本 mvn compile 编译 mvn test 测试 mvn package 打包 mvn clean 删除target mvn install 安装jar包到本地仓 ...

  10. FluentValidation具体使用案例

    可以使用NuGet 添加类库   下面是程序: using FluentValidation; using System; using System.Linq; namespace TestFluen ...