唉。。又调了半天QWQ。。为何读入挂了。。。。。莫非读入是反着的????据ywy学长所言如是。。。OvO震惊


这啥骚题啊、、、还要换根、、、不过清明讲过、、、(然鹅我现在才做、、、

先随便选个点(比如选1) 树剖板子一样搞一搞

1操作 就直接改root变量的值

2操作 线段树上改 换根不影响。。

3操作 分成三种情况 :

  1.rt = u 整个树的min就是ans

  2. lca(rt,u) != u 求u子树的min就好了 换根不影响

  3. lca(rt,u) = u 找一下rt在u的子树里,求这个子树的补集的min就好了

    比如rt在以v为根的u的子树中,那么如果dfn [ v ] > 1 先求 1到dfn  [ v ] - 1的 min , (如果dfn [ v ]+sz[ v ] <= n)  就再求一下 dfn[v]+sz[v] 到 n 的min

#include<cstdio>
#include<iostream>
#define R register int
#define ls (tr<<1)
#define rs (tr<<1|1)
using namespace std;
const int M=,Inf=0x7fffffff;
inline int g() {
R ret=; register char ch; while(!isdigit(ch=getchar()));
do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret;
}
int n,m,cnt,num,rt;
int vr[M<<],nxt[M<<],fir[M],w[M],top[M],son[M],pre[M],sz[M],d[M],dfn[M],rw[M];
int mn[M<<],tg[M<<];
inline void add(int u,int v) {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
inline void dfs(int u) { sz[u]=; R mx=;
for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
if(d[v]) continue; d[v]=d[u]+,pre[v]=u; dfs(v);
sz[u]+=sz[v]; if(sz[v]>mx) son[u]=v,mx=sz[v];
}
}
inline void dfs2(int u,int tp) { dfn[u]=++num,rw[num]=u,top[u]=tp;
if(son[u]) dfs2(son[u],tp);
for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
if(v!=son[u]&&v!=pre[u]) dfs2(v,v);
}
}
inline void build(int tr,int l,int r) {
if(l==r) {mn[tr]=w[rw[l]]; return ;} R md=l+r>>;
build(ls,l,md),build(rs,md+,r); mn[tr]=min(mn[ls],mn[rs]);
}
inline void spread(int tr) { if(tg[tr])
tg[ls]=tg[tr],mn[ls]=tg[tr],
tg[rs]=tg[tr],mn[rs]=tg[tr],tg[tr]=;
}
inline void update(int tr,int l,int r,int LL,int RR,int inc) {
if(LL<=l&&r<=RR) {mn[tr]=inc; tg[tr]=inc; return ;} spread(tr); R md=l+r>>;
if(LL<=md) update(ls,l,md,LL,RR,inc); if(RR>md) update(rs,md+,r,LL,RR,inc);
mn[tr]=min(mn[ls],mn[rs]);
}
inline int query(int tr,int l,int r,int LL,int RR) {
if(LL<=l&&r<=RR) return mn[tr]; spread(tr); R md=l+r>>,ret=Inf;
if(LL<=md) ret=min(ret,query(ls,l,md,LL,RR)); if(RR>md) ret=min(ret,query(rs,md+,r,LL,RR));
return ret;
}
inline int lca(int u,int v) {
while(top[u]!=top[v]) {
if(d[top[u]]<d[top[v]]) swap(u,v); u=pre[top[u]];
} return d[u]>d[v]?v:u;
}
inline void change(int u,int v,int inc) {
while(top[u]!=top[v]) {
if(d[top[u]]<d[top[v]]) swap(u,v);
update(,,n,dfn[top[u]],dfn[u],inc);
u=pre[top[u]];
} if(dfn[u]>dfn[v]) swap(u,v);
update(,,n,dfn[u],dfn[v],inc);
}
inline int getmn(int u) { R v,ret=Inf;
if(u==rt) return mn[];
R l=lca(u,rt);
if(l!=u) return query(,,n,dfn[u],dfn[u]+sz[u]-);
else for(R i=fir[u];i;i=nxt[i]) if(lca(vr[i],rt)==vr[i]) {v=vr[i]; break;}
if(dfn[v]>) ret=min(ret,query(,,n,,dfn[v]-));
if(dfn[v]+sz[v]<=n) ret=min(ret,query(,,n,dfn[v]+sz[v],n)); return ret;
}
signed main() {
n=g(),m=g();
for(R i=,u,v;i<n;++i) u=g(),v=g(),add(u,v),add(v,u);
for(R i=;i<=n;++i) w[i]=g(); d[]=; rt=g(); dfs(); dfs2(,);
build(,,n);
for(R i=;i<=m;++i) {
R k=g(),u=g(),v,inc;
if(k==) rt=u;
else if(k==) //change(u,g(),g());
v=g(),inc=g(),change(u,v,inc);
else if(k==) printf("%d\n",getmn(u));
}
}

2019.04.22

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 换根后路径还是不变,子树分类讨论一下,树剖后线段树维护即可. 代码如下: #inclu ...

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

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

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

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

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

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

随机推荐

  1. Go并发原理

    Go语言是为并发而生的语言,Go语言是为数不多的在语言层面实现并发的语言:也正是Go语言的并发特性,吸引了全球无数的开发者. 并发(concurrency)和并行(parallellism) 并发(c ...

  2. java之类和对象

    类的成员: 成员变量和成员函数. 成员函数:构造函数和普通函数. 构造函数: 作用:自动对对象进行初始化 特点:1.方法名和类名一致 2.没有返回值 问: 1.我们能够定义几次构造函数? 我们可以定义 ...

  3. 2018 - Start Up

    转眼2017已经过去,从大四下学期出来实习,到现在工作一年多了,很遗憾没有经营好自己博客园&CSDN. 献上一篇鼓励工程师写blog的博客:https://kb.cnblogs.com/pag ...

  4. 已看1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架、多线程(并发编程)、I/O(NIO)、Socket、JDBC、XML、反射等。[泛型]\

    1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架.多线程(并发编程).I/O(NIO).Socket.JDBC.XML.反射等.[泛型]\1* ...

  5. GCC 版本与C11标准

    1. GCC版本是否支持C11 C89=C90:gcc选项是:-ansi, -std=c90 or -std=iso9899:; 带了GNU扩展的:-std=gnu90 C94=C95:gcc选项:- ...

  6. python 简单的数据库操作之转账

    介绍:本文是关于数据库的简单操作,实现转账(只是修改数据库中用户的账户金额)的功能 模块介绍:首先是入口主函数 主函数中实现转账方法  以及异常的处理: if __name__ == "__ ...

  7. Mat类

    1.Mat类 早期的opencv中,使用IplImage和CvMat数据结构来表示图像.IplImage和 CvMat 都是c语言的结构.使用这两个结构的问题是内存需要手动管理,开发者必须清楚的知道何 ...

  8. Android 实现形态各异的双向侧滑菜单 自定义控件来袭(转载)

    1.概述 关于自定义控件侧滑已经写了两篇了~~今天决定把之前的单向改成双向,当然了,单纯的改动之前的代码也没意思,今天不仅会把之前的单向改为双向,还会多添加一种侧滑效果,给大家带来若干种形态各异的双向 ...

  9. 《Head First Servlets & JSP》-11-Web应用部署

    Web目录 WAR文件 WAR文件只是Web应用结构的一个快照,采用了一种更可移植的压缩形式. 建立WAR文件时,就是把整个Web应用结构(去掉Web应用上下文目录,就是把WEB-INF之上的一级目录 ...

  10. 小小c#算法题 - 8 - 归并排序 (Merging Sort)

    “归并”的含义是将两个或两个以上的有序序列组合成一个新的有序序列.这个“归并”可以在O(n+m)的数量级上实现,但这同时也需要O(n+m)的空间复杂度.具体为:首先分配一个新的长度为n+m的空序列,然 ...