洛谷链接

题意

给定一张无向图,点有点权,多次询问两点之间路径上点权最小的点的可能的最小值,支持修改点权。

Sol

一棵树就很简单 , 于是我们考虑点双(环)上的情况 , 直观想法就是缩完点双后一个点双的权值直接就是其中的最小值 , 这样我们要讨论的就是路径的起始端可能是在割点上的情况。

直接建一个广义圆方树就没有什么要多考虑的了。

把每一个点双找出来新建方点来代表。这样在圆方树上过了方点就相当与可以在点双里面随便走 , 那么方点的点权自然就是点双里所有点的点权的最小值了。

路径询问和修改点权就用个树剖+线段树。

不过这样的话修改一个圆点的点权时我们要修改它儿子集合的所有方点 , 复杂度就爆炸了。

所以我们对于一个方点不考虑它父亲的权值就行了,那么一个方点的权值就是去掉父亲圆点之后的点双上的点的权值的最小值。只需要最后如果两个点的 LCA 是一个方点的话把他的父亲圆点的权值也用来更新答案就好了。

所以我们还需要一个 可删除堆/multiset 来解决点权的变化问题。

要注意的一点是 , 对于桥边不要新建方点 , 容易被卡。

code:

#include<bits/stdc++.h>
using namespace std;
#define Set(a,b) memset(a,b,sizeof(a))
template<class T>inline void init(T&x){
x=0;char ch=getchar();bool t=0;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
if(t) x=-x;return;
}
int n,m,q;
const int N=1e5+10;
struct edge{int to,next;}a[N<<1];
int val[N],head[N],cnt=0;
inline void add(int x,int y){a[cnt]=(edge){y,head[x]};head[x]=cnt++;}
typedef pair<int,int> PA;
int Tn;
struct Heap{
priority_queue<int> P,Q;
inline void Delete(const int x){P.push(-x);}
inline void push(const int x){Q.push(-x);}
inline int top(){while(!P.empty()&&!Q.empty()&&P.top()==Q.top()) P.pop(),Q.pop();return -Q.top();}
}H[N];
namespace Tree{
const int N=2e5+10;
edge a[N<<1];int head[N],cnt=0,son[N],size[N],top[N],id[N],fa[N],dep[N],I=0,dfn[N];
inline void add(int x,int y){a[++cnt]=(edge){y,head[x]};head[x]=cnt;}
void dfs(int u){
size[u]=1;
for(int v,i=head[u];i;i=a[i].next){
v=a[i].to;if(v==fa[u]) continue;
fa[v]=u;dep[v]=dep[u]+1;dfs(v);
size[u]+=size[v];
if(!son[u]||size[son[u]]<size[v]) son[u]=v;
}return;
}
void Dfs(int u,int tp){
id[u]=++I;dfn[I]=u;top[u]=tp;
if(!son[u]) return;Dfs(son[u],tp);
for(int v,i=head[u];i;i=a[i].next) {
v=a[i].to;if(v==fa[u]||v==son[u]) continue;
Dfs(v,v);
}return;
}
#define ls (u<<1)
#define rs (u<<1|1)
int Mi[N<<2];
inline void update(int u){Mi[u]=min(Mi[ls],Mi[rs]);return;}
void Build(int u,int l,int r){
if(l==r) return void(Mi[u]=val[dfn[l]]);
int mid=l+r>>1;Build(ls,l,mid),Build(rs,mid+1,r);
return update(u);
}
inline void Prework(){dfs(1);Dfs(1,1);Build(1,1,n);}
int Query(int u,int l,int r,int L,int R){
if(l>=L&&r<=R) return Mi[u];int mid=l+r>>1;
if(mid>=R) return Query(ls,l,mid,L,R);
if(mid< L) return Query(rs,mid+1,r,L,R);
return min(Query(ls,l,mid,L,mid),Query(rs,mid+1,r,mid+1,R));
}
inline int Query(int u,int v){
if(u==v) return val[u];
int ans=min(val[u],val[v]);
while(top[u]^top[v]) {
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans=min(ans,Query(1,1,I,id[top[u]],id[u]));
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);int lca=u;
ans=min(ans,Query(1,1,I,id[u],id[v]));
if(lca>Tn) ans=min(ans,val[fa[lca]]);
return ans;
}
void Modify(int u,int l,int r,int p,int x){
if(l==r) return void(Mi[u]=x);
int mid=l+r>>1;
if(mid>=p) Modify(ls,l,mid,p,x);
else Modify(rs,mid+1,r,p,x);
update(u);
}
inline void Modify(int u,int w){
int f=fa[u];Modify(1,1,I,id[u],w);
int vu=val[u];val[u]=w;
if(f>Tn) {
int ID=f-Tn;
H[ID].Delete(vu);H[ID].push(w);
int nw=H[ID].top();
if(val[f]!=nw) val[f]=nw,Modify(1,1,I,id[f],nw);
}
}
}
#undef ls
#undef rs
PA stk[N];int bel[N],bcc=0,dfn[N],low[N],I=0,top=0;
void tarjan(int u,int ret) {
dfn[u]=low[u]=++I;
for(int v,i=head[u];~i;i=a[i].next){
v=a[i].to;if(ret==(i^1)) continue;
if(!dfn[v]) {
stk[++top]=PA(u,v);int nowt=top;
tarjan(v,i);
low[u]=min(low[v],low[u]);
if(low[v]>=dfn[u]) {
if(top!=nowt){
++bcc;++n;Tree::add(u,n);
while(top) {
int p=stk[top].first,q=stk[top].second;--top;
if(bel[p]!=bcc) {
bel[p]=bcc;
if(p^u) Tree::add(n,p),H[bcc].push(val[p]);
}
if(bel[q]!=bcc) {
bel[q]=bcc;
if(q^u) Tree::add(n,q),H[bcc].push(val[q]);
}
if(p==u&&q==v) break;
}
val[n]=H[bcc].top();
}
else --top,Tree::add(u,v);
}
}
else if(dfn[v]<dfn[u]) {stk[++top]=PA(u,v);low[u]=min(low[u],dfn[v]);}
}
}
int main()
{
init(n),init(m),init(q);Set(head,-1);Tn=n;
for(int i=1;i<=n;++i) init(val[i]);int u,v;
for(int i=1;i<=m;++i) {init(u),init(v);add(u,v),add(v,u);}
tarjan(1,-1);Tree::Prework();
for(int i=1;i<=q;++i) {
char ch=getchar();while(ch!='C'&&ch!='A') ch=getchar();
int a,w,b;
if(ch=='C') {init(a),init(w);Tree::Modify(a,w);}
else {init(a),init(b);printf("%d\n",Tree::Query(a,b));}
}
return 0;
}

【CF487E】Tourists的更多相关文章

  1. 【CF487E】Tourists(圆方树)

    [CF487E]Tourists(圆方树) 题面 UOJ 题解 首先我们不考虑修改,再来想想这道题目. 我们既然要求的是最小值,那么,在经过一个点双的时候,走的一定是具有较小权值的那一侧. 所以说,我 ...

  2. 【POJ1823】【线段树】Hotel

    Description The "Informatics" hotel is one of the most luxurious hotels from Galaciuc. A l ...

  3. hihoCoder 1578 Visiting Peking University 【贪心】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)

    #1578 : Visiting Peking University 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Ming is going to travel for ...

  4. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  5. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  6. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  7. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  8. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  9. Python高手之路【三】python基础之函数

    基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...

随机推荐

  1. docker英语

    demotevt. 使降级:使降职 promotevt. 促进:提升:推销:发扬 swarmn. 一大群:蜂群:人群:一大群小型天体同时在空中出现 worker 工人manager 经理swarm 人 ...

  2. Octavia 的实现与分析(OpenStack Rocky)

    目录 文章目录 目录 Octavia 基本对象概念 基本使用流程 软件架构 服务进程清单 代码结构 loadbalancer 创建流程分析 network_tasks.AllocateVIP netw ...

  3. Spring MVC集成Swagger2.0

    在集成Swagger之前,得先说说什么是Swagger,它是用来做什么的,然后再讲讲怎么集成,怎么使用,当然,在这之前,需要了解一下OpenAPI. OpenAPI OpenAPI 3.0规范定义了一 ...

  4. Jmeter之检查点

    检查点 Jmeter中检查点也叫断言,Jmeter中有很多类型的断言,但是最常用的是响应断言,即根据服务器返回的结果来判断测试是否通过. 响应断言 添加断言结果用于运行完毕后查看结果 测试通过 测试不 ...

  5. Lua增加一个节点到文件中

    新建一个文件touch /etc/config/ddns 增加一个节点到文件中uci set ddns.newadd=config <config>:即配置文件,如ddns,ipv6等&l ...

  6. vs2010发布网站时有些文件没有发布出去的解决办法。

    项目中包含了一些ttf字体文件做为图标使用,可是发布时发现生成的目录中没有这个文件,这种情况这么设置一下就可以解决: 1,在文件上点击右键,选择“属性”. 2,在弹出的属性窗口中,更改“生成操作”为“ ...

  7. JavaScript —— 实现简单计算器【带有 开/关机 清零 退格 功能】

    <!doctype html> <html> <head> <meta charset="utf-8"> <meta name ...

  8. springBoot(2) HelloWorld

    首先 下载一个 Spring Boot环境. 下载地址:https://spring.io/tools3/sts/all 打开STS.exe 一,新建项目 然后在空白处新建: 1.New→Other→ ...

  9. LeetCode.876-链表的中间节点(Middle of the Linked List)

    这是悦乐书的第337次更新,第361篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第206题(顺位题号是876).给定具有头节点的非空单链表,返回链表的中间节点.如果有两 ...

  10. CNN(卷积神经网络)原理讲解及简单代码

    一.原理讲解 1. 卷积神经网络的应用 分类(分类预测) 检索(检索出该物体的类别) 检测(检测出图像中的物体,并标注) 分割(将图像分割出来) 人脸识别 图像生成(生成不同状态的图像) 自动驾驶 等 ...