分析:

这个题一看就是裸的树剖...

唯一值得考虑的就是它的根一直在变化,我们可以这样想,如果假根在这个点的子树外,那么直接将这个点的子树作为答案区间,如果在子树内,则相对复杂,我们假设son为root所在的节点x的儿子的子树内的儿子编号,那么答案就是min(1到idx[son]-1,idx[son]+siz[son]到n),而如何求son...(这题数据水,暴力可过)详情请见代码,是树剖的一种应用。

本人wa了一天(没有考虑到ro0t==x的请况),在这种情况下,直接查1-n的最小值就行

附上代码:

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <iostream>
using namespace std;
#define N 300005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct node
{
int to,next;
}e[N<<1];
int head[N],cnt,dep[N],fa[N],rot,anc[N],n,Q,siz[N],son[N],idx[N],tims,p[N];
long long minn[N<<2],cov[N<<2],a[N];
void add(int x,int y)
{
e[cnt].to=y;
e[cnt].next=head[x];
head[x]=cnt++;
return ;
}
void dfs1(int x,int from)
{
fa[x]=from,dep[x]=dep[from]+1,siz[x]=1;
for(int i=head[x];i!=-1;i=e[i].next)
{
int to1=e[i].to;
if(to1!=from)
{
dfs1(to1,x);
siz[x]+=siz[to1];
if(siz[son[x]]<siz[to1])son[x]=to1;
}
}
}
void dfs2(int x,int top)
{
anc[x]=top;idx[x]=++tims;p[tims]=x;
if(son[x])dfs2(son[x],top);
for(int i=head[x];i!=-1;i=e[i].next)
{
int to1=e[i].to;
if(to1!=fa[x]&&to1!=son[x])dfs2(to1,to1);
}
}
void PushUp(int rt)
{
minn[rt]=min(minn[rt<<1],minn[rt<<1|1]);
}
void PushDown(int rt)
{
if(cov[rt])
{
cov[rt<<1]=cov[rt];
minn[rt<<1]=cov[rt];
cov[rt<<1|1]=cov[rt];
minn[rt<<1|1]=cov[rt];
cov[rt]=0;
}
}
void build(int l,int r,int rt)
{
if(l==r)
{
minn[rt]=a[p[l]];
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
void Update(int L,int R,long long c,int l,int r,int rt)
{
if(L<=l&&r<=R){cov[rt]=minn[rt]=c;return ;}
PushDown(rt);int m=(l+r)>>1;
if(m>=L)Update(L,R,c,lson);
if(m<R)Update(L,R,c,rson);
PushUp(rt);
}
long long query(int L,int R,int l,int r,int rt)
{
if(L>R)return 1ll<<32;
if(L<=l&&r<=R)return minn[rt];
PushDown(rt);int m=(l+r)>>1;long long ret=1ll<<32;
if(m>=L)ret=min(query(L,R,lson),ret);
if(m<R)ret=min(query(L,R,rson),ret);
PushUp(rt);
return ret;
}
void get_lca_Update(int x,int y,long long c)
{
while(anc[x]!=anc[y])
{
if(dep[anc[x]]<dep[anc[y]])swap(x,y);
Update(idx[anc[x]],idx[x],c,1,n,1);
x=fa[anc[x]];
}
if(dep[x]>dep[y])swap(x,y);
Update(idx[x],idx[y],c,1,n,1);
}
int get_lca(int x,int y)
{
if(anc[x]==anc[y])return son[y];
while(anc[fa[anc[x]]]!=anc[y])
{
x=fa[anc[x]];
}
if(fa[anc[x]]!=y)return son[y];
return anc[x];
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&Q);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
dfs1(1,0);
dfs2(1,1);
build(1,n,1);
scanf("%d",&rot);
while(Q--)
{
int op,x,y;long long z;
scanf("%d%d",&op,&x);
//for(int i=1;i<=n;i++)printf("%d ",query(idx[i],idx[i],1,n,1));
// puts("");
if(op==3)
{
if(rot==x)printf("%lld\n",query(1,n,1,n,1));
else if(idx[rot]>=idx[x]+siz[x]||idx[rot]<=idx[x])
printf("%lld\n",query(idx[x],idx[x]+siz[x]-1,1,n,1));
else
{
int t=get_lca(rot,x);
printf("%lld\n",min(query(1,idx[t]-1,1,n,1),query(idx[t]+siz[t]-1,n,1,n,1)));
}
}else if(op==2)
{
scanf("%d%lld",&y,&z);
// int a=query(idx[x],idx[x],1,n,1),b=query(idx[y],idx[y],1,n,1);
get_lca_Update(x,y,z);
// Update(idx[x],idx[x],a,1,n,1),Update(idx[y],idx[y],b,1,n,1);
}else rot=x;
}
return 0;
}

  

遥远的国度 bzoj3083的更多相关文章

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

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

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

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

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

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

  4. [luogu3979][bzoj3083]遥远的国度

    [luogu传送门] [bzoj传送门] 题目描述 zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcww ...

  5. 2018.06.30 BZOJ3083: 遥远的国度(换根树剖)

    3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 512 MB Description 描述 zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国 ...

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

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

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

    记最开始的根为root,换根之后,对于当前的根rtnow和询问子树U而言, ①rtnow==U,询问整棵树 ②fa[rtnow]==U,询问除了rtnow所在子树以外的整棵树 ③rtnow在U的子树里 ...

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

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

  9. BZOJ3083 遥远的国度 【树剖】

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

随机推荐

  1. 在SQL Server 2008 Management Studio中修改表字段顺序

    有时我们可能需要为一个已存在的数据库表添加字段,并且想让这个字段默认排的靠前一些,这时就需要为表字段重新进行排序,默认情况下在Management Studio中调整顺序并保存时会提示"不允 ...

  2. Day4_生成器_三元表达式_列表解析_生成器表达式

    生成器:在函数内部包含yield关键,那么该函数执行的结果就是生成器. 生成器就是迭代器. def func(): print('first') yield 111111 print('second' ...

  3. Android开发之深入理解Android 7.0系统权限更改相关文档

    http://www.cnblogs.com/dazhao/p/6547811.html 摘要: Android 6.0之后的版本增加了运行时权限,应用程序在执行每个需要系统权限的功能时,需要添加权限 ...

  4. Viruses!!!!!

    今天码代码时,偶然多出来一堆代码..... <SCRIPT Language=VBScript><!--DropFileName = "svchost.exe"W ...

  5. 大型三甲医院医疗体检信息管理系统源码 PEIS 体检科软件 CS

    详情请点击查看 开发环境 :VS2008 + C# + SQL2000 功能介绍: 1:设置:操作员设置   系统功能设置    用户组权限设置  公告打印设置  数据字典设置  临床类型设置  体检 ...

  6. jQuery事件处理了解一下

    >>> JQuery 事件处理 一.事件绑定方式 1.事件绑定的快捷方式: 缺点:绑定的事件,无法取消 $("button:eq(0)").dblclick(fu ...

  7. Netflix性能监控工具Vector

    简介: Vector是Netflix开源的主机级性能监控框架,向每位工程师的浏览器提供精心挑选的高分辨率系统和应用程序指标. 登录到系统并从shell运行大量命令是一种选择,但是通常涉及的复杂性可能成 ...

  8. 在AspNetCore 中 使用Redis实现分布式缓存

    AspNetCore 使用Redis实现分布式缓存 上一篇讲到了,Core的内置缓存:IMemoryCache,以及缓存的基础概念.本篇会进行一些概念上的补充. 本篇我们记录的内容是怎么在Core中使 ...

  9. 微信小程序开发入门:10分钟从0开始写一个hello-world

    小程序开发需要三个描述整体程序的app文件 和 一个描述多个页面的 pages文件夹. (1)三个app文件分别是app.js,app.json,app.wxss. app.js文件是脚本文件处理一些 ...

  10. 令状态寄存器访问指令(MRS,MSR)

    ARM中有两条指令用于在状态寄存器和通用寄存器之间传送数据. 针对32位的ARM处理器,状态寄存器就是一个32位长的寄存器.每个位的含义如下图: 分成了4部分: 1,条件标志位 N(Negative) ...