【CF487E】Tourists
题意
给定一张无向图,点有点权,多次询问两点之间路径上点权最小的点的可能的最小值,支持修改点权。
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的更多相关文章
- 【CF487E】Tourists(圆方树)
[CF487E]Tourists(圆方树) 题面 UOJ 题解 首先我们不考虑修改,再来想想这道题目. 我们既然要求的是最小值,那么,在经过一个点双的时候,走的一定是具有较小权值的那一侧. 所以说,我 ...
- 【POJ1823】【线段树】Hotel
Description The "Informatics" hotel is one of the most luxurious hotels from Galaciuc. A l ...
- hihoCoder 1578 Visiting Peking University 【贪心】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
#1578 : Visiting Peking University 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Ming is going to travel for ...
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 【原】谈谈对Objective-C中代理模式的误解
[原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【调侃】IOC前世今生
前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...
- Python高手之路【三】python基础之函数
基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...
随机推荐
- EDM案例讲解:Mouth foods的EDM邮件营销
你可能没有听说过Mouth foods,它是一个美味产品的在线市场.作为一个日益增长的企业,他们知道电子邮件的重要性,因为在此之前他们通过电子邮件真正找到了企业品牌中的自我,这就是为什么他们认为电子邮 ...
- Selenium学习之==>Selenium介绍
前世 Selenium RC 早期的Selenium使用的是JavaScript注入技术与浏览器打交道,需要Selenium RC启动一个Server,将操作Web元素的API调用转化为一段段Java ...
- 数据库之DML
1.表的有关操作: 1.1.表的创建格式: CREATE TABLE IF NOT EXISTS 表名(属性1 类型,属性2 类型,....,属性n 类型):# 标记部分表示可以省略 1.2.表的修改 ...
- C# 编写的webservice 怎样返回XML数据
[WebMethod] public string GetXml() { string sConStr = ConfigurationManager.ConnectionStrings["c ...
- 无法识别的配置节log4net的(Unrecognized configuration section log4net)
每个配置文件中只允许存在一个 <configSections> 元素,并且,如果存在该元素,它还必须是根 <configuration> 元素的第一个子元素. 问题: I ha ...
- STL 函数适配器(function adapter)
函数适配器(function adapter):通过不同函数适配器的绑定,组合和修饰能力,可以实现强大的功能,配合STL泛型算法完成复杂功能. 绑定(bind) template <class ...
- 第十三周学习总结 Java的异常
java的核心思想 面向对象的编程思想 类和类的关系 类中成员的描述 对象创建 Java工具类 包装类 数学相关 日期相关 字符串相关 集合相关的类 考试机 学生 老师 --------------- ...
- https=http+ssl
TLS/SSL中使用了非对称加密,对称加密以及HASH算法.握手过程的具体描述如下: 浏览器将自己支持的一套加密规则发送给网站. 网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式 ...
- SpringBoot项目快速启动停止脚本
SpringBoot项目快速启动停止脚本 1.在jar包同级目录下,创建 app.sh #!/bin/bash appName=`ls|grep .jar$` if [ -z $appName ] t ...
- [转帖]NetSuite 进入中国市场满一年,甲骨文公布首份成绩单
NetSuite 进入中国市场满一年,甲骨文公布首份成绩单 https://baijiahao.baidu.com/s?id=1617073148682281883&wfr=spider&am ...