传送门

先把边双连通分量用圆方树一样的方法缩点,然后把新建的树树剖维护。

注意对于边双连通分量需要维护动态最小值,可以用multisetmultisetmultiset。

代码:

#include<bits/stdc++.h>
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
const int N=2e5+5,M=3e5+5;
int siz[N],w[N<<1],top[N],dep[N],pred[N],hson[N],num[N],dfn[N],low[N],tot=0,sig=0,n,m,q,blo[N],stk[N],Top=0,fa[N];
struct Node{int l,r,mn;}T[N<<2];
vector<int>g[N],e[N<<1];
multiset<int>W[N<<1];
inline void tarjan(int p,int pre){
	dfn[p]=low[p]=++tot,stk[++Top]=p;
	for(int i=0;i<g[p].size();++i){
		int v=g[p][i];
		if(v==pre)continue;
		if(!dfn[v]){
			tarjan(v,p),low[p]=min(low[p],low[v]);
			if(low[v]>=dfn[p]){
				int tmp;
				++sig,e[p].push_back(sig);
				do tmp=stk[Top--],blo[tmp]=sig,e[sig].push_back(tmp),W[sig].insert(w[tmp]);while(tmp^v);
				w[sig]=*(W[sig].begin());
			}
		}
		else low[p]=min(low[p],dfn[v]);
	}
}
inline void dfs1(int p){
	siz[p]=1;
	for(int i=0;i<e[p].size();++i){
		int v=e[p][i];
		if(v==fa[p])continue;
		fa[v]=p,dep[v]=dep[p]+1,dfs1(v),siz[p]+=siz[v];
		if(siz[v]>siz[hson[p]])hson[p]=v;
	}
}
inline void dfs2(int p,int tp){
	top[p]=tp,pred[num[p]=++tot]=p;
	if(!hson[p])return;
	dfs2(hson[p],tp);
	for(int i=0;i<e[p].size();++i){
		int v=e[p][i];
		if(v!=fa[p]&&v!=hson[p])dfs2(v,v);
	}
}
inline void pushup(int p){T[p].mn=min(T[lc].mn,T[rc].mn);}
inline void build(int p,int l,int r){
	T[p].l=l,T[p].r=r;
	if(l==r){T[p].mn=w[pred[l]];return;}
	build(lc,l,mid),build(rc,mid+1,r),pushup(p);
}
inline void update(int p,int k,int v){
	if(T[p].l==T[p].r){T[p].mn=v;return;}
	if(k<=mid)update(lc,k,v);
	else update(rc,k,v);
	pushup(p);
}
inline int query(int p,int ql,int qr){
	if(ql<=T[p].l&&T[p].r<=qr)return T[p].mn;
	if(qr<=mid)return query(lc,ql,qr);
	if(ql>mid)return query(rc,ql,qr);
	return min(query(lc,ql,mid),query(rc,mid+1,qr));
}
inline int ask(int x,int y){
	int ret=1e9;
	while(top[x]^top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		ret=min(ret,query(1,num[top[x]],num[x])),x=fa[top[x]];
	}
	if(dep[x]<dep[y])swap(x,y);
	ret=min(query(1,num[y],num[x]),ret);
	if(y>n&&fa[y])ret=min(ret,w[fa[y]]);
	return ret;
}
inline void modify(int p,int v){
	if(blo[p]){
		set<int>::iterator it=W[blo[p]].find(w[p]);
		W[blo[p]].erase(it),W[blo[p]].insert(v),w[blo[p]]=*(W[blo[p]].begin()),update(1,num[blo[p]],w[blo[p]]);
	}
	w[p]=v,update(1,num[p],v);
}
int main(){
	sig=n=read(),m=read(),q=read();
	for(int i=1;i<=n;++i)w[i]=read();
	for(int i=1,u,v;i<=m;++i)u=read(),v=read(),g[u].push_back(v),g[v].push_back(u);
	tarjan(1,0),dfs1(1),tot=0,dfs2(1,1),build(1,1,sig);
	for(int i=1,x,y;i<=q;++i){
		char s[5];
		scanf("%s",s),x=read(),y=read();
		if(s[0]=='C')modify(x,y);
		else printf("%d\n",ask(x,y));
	}
}

2018.11.09 codeforces487E. Tourists(tarjan+树链剖分)的更多相关文章

  1. JZYZOJ1454 NOIP2015 D2T3_运输计划 二分 差分数组 lca tarjan 树链剖分

    http://172.20.6.3/Problem_Show.asp?id=1454 从这道题我充分认识到我的脑子里好多水orz. 如果知道了这个要用二分和差分写,就没什么思考上的难点了(屁咧你写了一 ...

  2. 2018.10.12 bzoj4712: 洪水(树链剖分)

    传送门 树链剖分好题. 考虑分开维护重儿子和轻儿子的信息. 令f[i]f[i]f[i]表示iii为根子树的最优值,h[i]h[i]h[i]表示iii重儿子的最优值,g[i]g[i]g[i]表示iii所 ...

  3. 【BZOJ4568】幸运数字(线性基,树链剖分,ST表)

    [BZOJ4568]幸运数字(线性基,树链剖分,ST表) 题面 BZOJ Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市 ...

  4. 【BZOJ1036】树的统计Count(树链剖分,LCT)

    题意:一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: ...

  5. 2018.09.16 bzoj3626: [LNOI2014]LCA(树链剖分)

    传送门 树链剖分好题. 对于每个点维护一个值vi" role="presentation" style="position: relative;"&g ...

  6. 2018.08.09 bzoj4719: [Noip2016]天天爱跑步(树链剖分)

    传送门 话说开始上文化课之后写题时间好少啊. 这道题将一个人的跑步路线拆成s->lca,lca->t,然后对于第一段上坡路径要经过的点,当前这个人能对它产生贡献当且仅当dep[s]-dep ...

  7. BZOJ_4326_[NOIP2015]_运输计划_(二分+LCA_树链剖分/Tarjan+差分)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=4326 给出一棵带有边权的树,以及一系列任务,任务是从树上的u点走到v点,代价为u到v路径上的权 ...

  8. 2018.06.29 洛谷P1505 [国家集训队]旅游(树链剖分)

    旅游 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有 ...

  9. [集训队作业2018]蜀道难——TopTree+贪心+树链剖分+链分治+树形DP

    题目链接: [集训队作业2018]蜀道难 题目大意:给出一棵$n$个节点的树,要求给每个点赋一个$1\sim n$之内的权值使所有点的权值是$1\sim n$的一个排列,定义一条边的权值为两端点权值差 ...

随机推荐

  1. Oracle触发器用法实例详解

    转自:https://www.jb51.net/article/80804.htm. 本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件 ...

  2. android.support.v4与Android.support.v7

    Android提供了android.support.v4和android.support.v7两个库,以便低版本API可以使用高版本API的功能. Fragment(碎片)类,是在Android 3. ...

  3. HDU 3251 Being a Hero(最小割+输出割边)

    Problem DescriptionYou are the hero who saved your country. As promised, the king will give you some ...

  4. 在linux 中启动anaconda

    anaconda-navigator   $ source ~/anaconda3/bin/activate root ###在bin  目录下打开终端 敲 ./activate root   $ a ...

  5. 面向对象中的property装饰器讲解

    面向对象中可以用property来修饰我们的函数,必须下面的例子 class Test(object): def __init__(self,name): self.name = name @prop ...

  6. Redis 与Spring-data-redis 整合后封装的工具类

    此工具类方法是使用了redis 与spring 整合后,才可以使用的工具类,将 spring-data-redis 一些我们开发中常用的方法进行了封装,方便我们日常开发中进行调用: package c ...

  7. MongoDB的增、删、改、查操作(五)

    按照我们关系型数据库的思想,一个服务器要想存放数据,首先要有数据库,表,字段,约束,当然了也少不了主键,外键,索引,关系等: 但是在MongoDB的世界里边,我们不用预先的去创建这些信息从而直接来使用 ...

  8. check-versions.js和dev-client.js

    // 用于在控制台输出带颜色字体的插件var chalk = require('chalk') // 语义化版本检查插件(The semantic version parser used by npm ...

  9. classpath分析

    1. 什么是classpath? classpath相当于Java执行环境,它指定了一些常用的包或jar的位置,方便我们对项目文件的使用,而不必重复多次写所需要文件的位置.    在classpath ...

  10. android apk 反编译过程

    一.准备必要的工具 apktool (资源文件获取) dex2jar(源码文件获取) jd-gui  (源码查看) 以上三个文件的下载地址为:https://download.csdn.net/dow ...