【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 ...
随机推荐
- JavaScript对象的常用属性及使用
什么是浏览器对象模型? 浏览器对象模型(BOM Browser Object Model)是JavaScript的组成之一,它提供了独立于内容和浏览器窗口进行交互的对象,使用浏览器对象模型可以实现与H ...
- 阶段3 1.Mybatis_10.JNDI扩展知识_3 补充-测试JNDI数据源的使用以及使用细节
在webapp文件夹下新建目录META-INF 把context.xml文件复制过去. 拿资料里面的SqlMapConfig.xml文件 全部复制到项目的SqlMapConfig.xml里面来. ja ...
- SPA(single page application)
一.SPA的概述 SPA(single page application)单页面应用程序,在一个完成的应用或者站点中,只有一个完整的html页面,这个页面有一个容器,可以把需要加载的代码片段插入到该容 ...
- 快速编写 <a> ————CSS3
a{ text-decoration:none; } a:link{ color:white; } a:visited { color:white; } a:hover { color:blue; } ...
- CSS3—— 2D转换 3D转换 过渡 动画
2D转换 对元素进行移动.缩放.转动.拉长或拉伸 ————> ————> 移动 顺时针旋转 扩大/缩小 倾斜 2D变换合并 3D转换 绕x轴 绕y轴 过渡 从一种样式逐渐改变为另一 ...
- 关于WordPress中字体加载慢的问题解决方案(转)
2016-04-15 最近发现Wordpress有时候加载的特别慢,于是就想办法找了下原因.之前听网上说是因为wordpress用的是Google的字体库,而且是每次都要加载,导致访问慢的,于是当时装 ...
- [Web 前端] 028 jQuery 事件
目录 jQuery 的事件 1. 事件绑定 1.1 事件的获取 1.2 基本绑定 1.3 动态绑定 2. 事件触发 2.1 触发的写法 2.2 常用的鼠标事件 3. 事件冒泡和默认行为 3.1 事件冒 ...
- [19/05/28-星期二] JavaScript_ 对象和引用数据类型
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Windows消息理解(系统消息队列,进程消息队列,非队列消息)
// ====================Windows消息分类==========================在Windows中,消息分为以下三类:标准消息——除WM_COMMAND之外,所 ...
- 关于css清除浮动
1.overflow:hidden 较简单,兼容于市面浏览器.负面效果不详.暂不推荐使用.2.定义clear类,并把clear类赋给浮动元素的父级元素. .clear{display:block;ov ...