题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083

换根后路径还是不变,子树分类讨论一下,树剖后线段树维护即可。

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid ((l+r)>>1)
#define ls (x<<1)
#define rs (x<<1|1)
using namespace std;
typedef long long ll;
int const xn=1e5+;
int n,m,hd[xn],ct,to[xn<<],nxt[xn<<],rt;
int tim,dfn[xn],fa[xn],siz[xn],son[xn],dep[xn],top[xn],id[xn];
ll a[xn],mn[xn<<],lzy[xn<<],inf=1e17;
ll rd()
{
ll ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
ll minn(ll x,ll y){return x<y?x:y;}
void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
void dfs(int x,int ff)
{
fa[x]=ff; dep[x]=dep[ff]+; siz[x]=;
for(int i=hd[x],u;i;i=nxt[i])
{
if((u=to[i])==ff)continue;
dfs(u,x); siz[x]+=siz[u];
if(siz[u]>siz[son[x]])son[x]=u;
}
}
void dfsx(int x)
{
dfn[x]=++tim; id[tim]=x;
if(son[x])top[son[x]]=top[x],dfsx(son[x]);
for(int i=hd[x],u;i;i=nxt[i])
if((u=to[i])!=fa[x]&&u!=son[x])top[u]=u,dfsx(u);
}
void build(int x,int l,int r)
{
if(l==r){mn[x]=a[id[l]]; return;}//id!!
build(ls,l,mid); build(rs,mid+,r);
mn[x]=minn(mn[ls],mn[rs]);
}
void turn(int x,ll v){mn[x]=v; lzy[x]=v;}
void pushdown(int x)
{
if(!lzy[x])return;
turn(ls,lzy[x]); turn(rs,lzy[x]);
lzy[x]=;
}
void update(int x,int l,int r,int L,int R,ll v)
{
if(l>=L&&r<=R){turn(x,v); return;}
pushdown(x);
if(mid>=L)update(ls,l,mid,L,R,v);
if(mid<R)update(rs,mid+,r,L,R,v);
mn[x]=minn(mn[ls],mn[rs]);
}
ll query(int x,int l,int r,int L,int R)
{
if(L>R)return inf;
if(l>=L&&r<=R)return mn[x];
pushdown(x); ll ret=inf;
if(mid>=L)ret=minn(ret,query(ls,l,mid,L,R));
if(mid<R)ret=minn(ret,query(rs,mid+,r,L,R));
return ret;
}
void change(int x,int y,ll v)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
update(,,n,dfn[top[x]],dfn[x],v); x=fa[top[x]];
}
if(dep[x]<dep[y])swap(x,y);
update(,,n,dfn[y],dfn[x],v);
}
int find(int x,int y)//y in x
{
while(top[y]!=top[x])
{
if(fa[top[y]]==x)return top[y];
y=fa[top[y]];
}
return son[x];
}
ll ask(int x)
{
if(x==rt)return query(,,n,,n);
if(dfn[rt]<dfn[x]||dfn[rt]>=dfn[x]+siz[x])
return query(,,n,dfn[x],dfn[x]+siz[x]-);
int y=find(x,rt);
return minn(query(,,n,,dfn[y]-),query(,,n,dfn[y]+siz[y],n));
}
int main()
{
n=rd(); m=rd();
for(int i=,x,y;i<n;i++)x=rd(),y=rd(),add(x,y),add(y,x);
dfs(,); top[]=; dfsx();
for(int i=;i<=n;i++)a[i]=rd();
build(,,n);
rt=rd(); ll z;
for(int i=,opt,x,y;i<=m;i++)
{
opt=rd(); x=rd();
if(opt==)rt=x;
if(opt==)y=rd(),z=rd(),change(x,y,z);
if(opt==)printf("%lld\n",ask(x));
}
return ;
}

bzoj 3083 遥远的国度 —— 树链剖分的更多相关文章

  1. BZOJ 3083 遥远的国度 树链剖分

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 797  Solved: 181[Submit][Status] Descrip ...

  2. BZOJ 3083 遥远的国度(树链剖分+LCA)

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

  3. BZOJ 3083: 遥远的国度(树链剖分+DFS序)

    可以很显而易见的看出,修改就是树链剖分,而询问就是在dfs出的线段树里查询最小值,但由于这道题会修改根节点,所以在查询的时候需判断x是否为root的祖先,如果不是就直接做,是的话应该查询从1-st[y ...

  4. BZOJ 3083 遥远的国度 树链剖分+线段树

    有换根的树链剖分的裸题. 在换根的时候注意讨论. 注意数据范围要开unsigned int或longlong #include<iostream> #include<cstdio&g ...

  5. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  6. bzoj 3083 遥远的国度——树链剖分+线段树维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 int 的范围是 2^31 - 1 ,所以权值是不是爆 int 了…… O( nlog ...

  7. BZOJ 3083 遥远的国度 树链剖分+脑子

    唉..又调了半天QWQ..为何读入挂了.....莫非读入是反着的????据ywy学长所言如是...OvO震惊 这啥骚题啊...还要换根...不过清明讲过...(然鹅我现在才做... 先随便选个点(比如 ...

  8. BZOJ 2243 染色 | 树链剖分模板题进阶版

    BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...

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

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

随机推荐

  1. Python中的TCP编程,实现客户端与服务器的聊天(socket)

    参考大神blog:自己再写一个 https://blog.csdn.net/qq_31187881/article/details/79067644

  2. xCode9 一直Indexing

    解决办法:打开终端输入:defaults write com.apple.dt.XCode IDEIndexDisable 1 然后重新打开工程就可以了

  3. dva+antd写的一个react例子

    github地址 https://github.com/shenggen1987/dva-cli-demo 效果图片

  4. android 自定义progressbar 样式

    在res下创建drawable文件夹,新建文件drawable/progressbar_color.xml <layer-list xmlns:android="http://sche ...

  5. Ruby 循环

    Ruby while 语句: 语法: while conditional [do] codeend 执行代码当条件为true时.while循环的条件是代码中的保留字,换行,反斜杠()或一个分号隔开. ...

  6. PAT 天梯赛 L2-010. 排座位 【并查集】

    题目链接 https://www.patest.cn/contests/gplt/L2-010 思路 因为 题意中 朋友的朋友 就是朋友 那么 朋友的关系 用 并查集 保存 但是 敌对关系 只有直接的 ...

  7. 每天一个Linux命令(33)cal命令

          cal命令用于显示当前日历,或者指定日期的日历.   (1)用法: 用法: cal [选项]  [[[日] 月] 年] (2)功能:       功能:  用于查看日历等时间信息,如只有一 ...

  8. linux共享库加载

    参考自: <<程序员的自我修养--链接.装载与库>> 第八章 Linux共享库的组织 以下截取部分内容 (这本书比较好的讲解了从程序的链接,装载,到运行) 共享库的兼容性 li ...

  9. 使用 sqoop 将 hive 数据导出到 mysql (export)

    使用sqoop将hive中的数据传到mysql中 1.新建hive表 hive> create external table sqoop_test(id int,name string,age ...

  10. Storm- 使用Storm实现词频汇总

    需求:读取指定目录的数据,并实现单词计数的功能 实现方案: Spout来读取指定目录的数据,作为后续Bolt处理的input 使用一个Bolt把input 的数据,切割分开,我们按照逗号进分割 使用一 ...