分析:

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

唯一值得考虑的就是它的根一直在变化,我们可以这样想,如果假根在这个点的子树外,那么直接将这个点的子树作为答案区间,如果在子树内,则相对复杂,我们假设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. Git的fast forward和no fast forward和 three way merge 以及squash(聚合)

    github上上传了版本库https://github.com/ChuckGitMerge   包括merge和rebase 没时间画图,貌似也不太会用画图工具,先写了一个文字版本的 更新:2015年 ...

  2. Web安全学习计划

    http://cisps.org/bbs/viewtopic.php?f=71&t=26125 标题为Web安全学习计划,实属我的愿望:将下面这份Web学习清单完善成为一个Web安全,学习计划 ...

  3. SQLServer2PostgreSQL迁移过程中的几个问题

    1.PostgreSQL 跨平台迁移工具Migration Toolkit的使用指南:http://www.enterprisedb.com/docs/en/8.4/mtkguide/Table%20 ...

  4. phone number

    problem description: you should change the given digits string into possible letter string according ...

  5. 五分钟学会centos配置gitlab

    下载gitlab 亲测: centos6.5 安装依赖包: : yum install curl policycoreutils policycoreutils-python openssh-serv ...

  6. Flask请求扩展和数据库连接池

    1.1.Flask之请求扩展 #!/usr/bin/env python # -*- coding:utf-8 -*- from flask import Flask, Request, render ...

  7. 洛谷 P1430 解题报告

    P1430 序列取数 题目描述 给定一个长为\(n\)的整数序列\((n<=1000)\),由\(A\)和\(B\)轮流取数(\(A\)先取).每个人可从序列的左端或右端取若干个数(至少一个), ...

  8. Python_二叉树

    BinaryTree.py '''二叉树:是每个节点最多有两个子树(分别称为左子树和右子树)的树结构,二叉树的第i层最多有2**(i-1)个节点,常用于排序或查找''' class BinaryTre ...

  9. hexo+github创建属于自己的博客

    配置环境 安装Node(必须) 作用:用来生成静态页面的 到Node.js官网下载相应平台的最新版本,一路安装即可. 安装Git(必须) 作用:把本地的hexo内容提交到github上去. 安装Xco ...

  10. Spark Streaming入门

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文将帮助您使用基于HBase的Apache Spark Streaming.Spark Streaming是Spark API核心的一个扩 ...