一无聊就找树剖写

题意:一颗带点权的树,三种操作:1.换根 2.链赋值 3.查询子树最小值


如果没有换根的话直接就是裸的树剖了,对于换根的操作我们可以分类讨论。

1.如果查询的$x$就是根,那答案就是整棵树的最小值。

2.如果以1为根的dfs序中,根在$x$的子树之外,那很明显$x$的子树还是原来的子树。

3.如果以1为根的dfs序中,根在$x$的子树里面的话,画个图就能发现,找到$x$的孩子中作为根的父亲那个点,答案就是整棵树把整个点的子树去掉就行了。

其他地方跟树剖没什么区别…

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lint;
const int N=100005;
const lint INF=(1ll<<32);
inline lint read()
{
lint s=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){s=s*10+c-'0';c=getchar();}
return s*f;
}
struct edge
{
int to,nxt;
}edges[N<<1];
int n,m,cnt,rot,tot;
int head[N<<1],son[N],size[N],dep[N],top[N],dl[N],dr[N],rk[N],fa[N];
lint tr[N<<2],tag[N<<2],v[N]; #define lson (o<<1)
#define rson (o<<1|1)
inline void push_up(int o)
{
tr[o]=min(tr[lson],tr[rson]);
}
inline void push_down(int o)
{
if(tag[o]==-1)return;
tag[lson]=tag[rson]=tag[o];
tr[lson]=tr[rson]=tag[o];
tag[o]=-1;
}
inline void build(int o,int l,int r)
{
tag[o]=-1;
if(l==r)
{
tr[o]=v[rk[l]];
return;
}int mid=(l+r)>>1;
build(lson,l,mid);build(rson,mid+1,r);
push_up(o);
}
inline void modify(int o,int l,int r,int ql,int qr,lint val)
{
if(ql<=l&&r<=qr)
{
tag[o]=tr[o]=val;
return;
}push_down(o);
int mid=(l+r)>>1;
if(mid>=ql)modify(lson,l,mid,ql,qr,val);
if(mid+1<=qr)modify(rson,mid+1,r,ql,qr,val);
push_up(o);
}
inline lint query(int o,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)return tr[o];
push_down(o);
int mid=(l+r)>>1;lint res=INF;
if(mid>=ql)res=min(res,query(lson,l,mid,ql,qr));
if(mid+1<=qr)res=min(res,query(rson,mid+1,r,ql,qr));
return res;
} #undef lson
#undef rson
inline void addEdge(int u,int v)
{
edges[++cnt]=(edge){v,head[u]};
head[u]=cnt;
}
#define cur edges[i].to
inline void dfs1(int x)
{
size[x]=1;
for(register int i=head[x];i;i=edges[i].nxt)
if(cur!=fa[x])
{
fa[cur]=x;dep[cur]=dep[x]+1;
dfs1(cur);size[x]+=size[cur];
if(size[son[x]]<size[cur])son[x]=cur;
}
}
inline void dfs2(int x,int t)
{
top[x]=t;dl[x]=++tot;rk[tot]=x;
if(son[x])dfs2(son[x],t);
for(register int i=head[x];i;i=edges[i].nxt)
if(cur!=fa[x]&&cur!=son[x])dfs2(cur,cur);
dr[x]=tot;
}
#undef cur
inline void modify_link(int a,int b,int val)
{
while(top[a]!=top[b])
{
if(dep[top[a]]<dep[top[b]])swap(a,b);
modify(1,1,n,dl[top[a]],dl[a],val);
a=fa[top[a]];
}
if(dep[a]>dep[b])swap(a,b);
modify(1,1,n,dl[a],dl[b],val);
}
inline lint query_tree(int x)
{
if(rot==x)return query(1,1,n,1,n);
if(dl[x]<=dl[rot]&&dl[rot]<=dr[x])
{
int y;
for(register int i=head[x];i;i=edges[i].nxt)
if(dl[edges[i].to]<=dl[rot]&&dl[rot]<=dr[edges[i].to])
{
y=edges[i].to;
break;
}
return min(query(1,1,n,1,dl[y]-1),query(1,1,n,dr[y]+1,n));
}else
{
return query(1,1,n,dl[x],dr[x]);
}
}
int main()
{
n=read();m=read();rot=1;
for(register int i=1;i<n;i++)
{
int u,v;u=read();v=read();
addEdge(u,v);addEdge(v,u);
}
for(register int i=1;i<=n;i++)v[i]=read();
rot=read();
dfs1(1);dfs2(1,1);build(1,1,n);
for(register int i=1;i<=m;i++)
{
int op,x,y,val;op=read();
if(op==1)
{
rot=read();
}else if(op==2)
{
x=read();y=read();val=read();
modify_link(x,y,val);
}else
{
x=read();
printf("%lld\n",query_tree(x));
}
}
}

[日常摸鱼]bzoj3083遥远的国度-树链剖分的更多相关文章

  1. BZOJ3083: 遥远的国度(树链剖分)

    题意 $n$个节点的树,每个点有权值,支持三种操作 1. 换根 2.把$x$到$y$路径上节点权值变为$z$ 3.询问路径最小值 Sol 啥?你说这是TopTree的裸题?那你写去啊 很显然,如果没有 ...

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

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

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

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

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

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

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

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

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

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

  7. 洛谷P3979 遥远的国度 树链剖分+分类讨论

    题意:给出一棵树,这棵树每个点有权值,然后有3种操作.操作一:修改树根为rt,操作二:修改u到v路径上点权值为w,操作三:询问以rt为根x子树的最小权值. 解法:如果没有修改树根操作那么这题就是树链剖 ...

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

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

  9. luoguP3979 遥远的国度 树链剖分

    \(1, 2\)操作没什么好说的 对于\(3\)操作,分三种情况讨论下 \(id = rt\)的情况下,查整棵树的最小值即可 如果\(rt\)在\(1\)号点为根的情况下不在\(id\)的子树中,那么 ...

随机推荐

  1. 掌握Python可以去哪些岗位?薪资如何?

    一.人工智能 Python作为人工智能的黄金语言,选择人工智能作为就业方向是理所当然的,就业前景也还不错.人工智能工程师的招聘起薪一般在20K-35K,如果是初级工程师,起薪一般12K. 二.大数据 ...

  2. 教你在CorelDRAW中制作水印

    水印是一种数字保护的手段,在图像上添加水印即能证明本人的版权,还能对版权的保护做出贡献.也就是在图片上打上半透明的标记,因其具有透明和阴影的特性,使之不管在较为阴暗或明亮的图片上都能完美使用,嵌入的水 ...

  3. Java中的位掩码BitMask

    目录 JDK源码的使用 日常工作中的使用 JDK源码的使用 最近在JDK源码中闲逛,无意中看到了java.lang.reflect.Modifier这个类,这个类很简单,都是些常量定义和判断方法,于是 ...

  4. 听说高手都用记事本写C语言代码?那你知道怎么编译运行吗?

    坊间传闻高手都喜欢用记事本写代码,那么问题来了,我们以C语言为例,如何用记事本编译运行呢?其实最简单的方式就是安装GCC编译器,在记事本编写C语言程序,然后再在命令行用GCC编译运行,下面我简单介绍一 ...

  5. FDR校正

    一.假设检验 假设检验的基本思路是: 设立零假设(null hypothesis)H0,以及与零假设H0相对应的非零假设(alternative hypothesis)H1,在假设H0成立的前提下,计 ...

  6. python之Bug之字符串拼接bug

    \r\n拼接Bug 环境: python3.4.pycharm2017 偶然的学习中遇到了一个问题,百思不得姐,什么问题呢,大家输入太快了,难免有失误就如下面的代码 #构造响应数据 response_ ...

  7. java并发编程实战《七》安全性、活跃性以及性能问题

    安全性.活跃性以及性能问题 安全性问题 那什么是线程安全呢?其实本质上就是正确性,而正确性的含义就是程序按照我们期望的执行,不要让我们感到意外. 存在共享数据并且该数据会发生变化,通俗地讲就是有多个线 ...

  8. OpenCV-Python setMouseCallback回调函数中图像变量img的传递方法解析

    ☞ ░ 前往老猿Python博文目录 ░ 一.使用全局变量进行变量传递 OpenCV-Python中可以使用setMouseCallback来设置鼠标事件的回调函数,我们来看个样例. 1.1.案例1代 ...

  9. moviepy用VideoFileClip加载视频时报UnicodeDecodeError: utf-8 codec cant decode byte invalid start byte错误

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 使用moviepy用: clip1 = Video ...

  10. Python中自定义类未定义__lt__方法使用sort/sorted排序会怎么处理?

    在<第8.23节 Python中使用sort/sorted排序与"富比较"方法的关系分析>中介绍了排序方法sort和函数sorted在没有提供key参数的情况下默认调用 ...