CF487E Tourists(圆方树+树链剖分+multiset/可删堆)
CF487E Tourists(圆方树+树链剖分+multiset/可删堆)
给出一个带点权的无向图,两种操作:
1、修改某点点权。
2、询问x到y之间简单路径能走过的点的最小点权。
题解时间
总感觉是将一堆水题拼出来的丑陋产物(划去)
毫无疑问看题直接搞上圆方树。
用可删堆或者multiset维护方点的权值。
查询直接树剖搞。
但这样会发现修改时间复杂度无法保证。
所以改成每个方点只记录子节点的权值。
当lca为方点时答案计算一下它上面的圆点。
$ O(nlog^{2}n) $
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
typedef long long lint;
template<typename TP>inline void read(TP &tar)
{
	TP ret=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}
	tar=ret*f;
}
namespace RKK
{
const int N=200011;
struct superheap
{
	priority_queue<int> q0,q1;
	int size;
	int top(){update();return -q0.top();}
	void push(int x){q0.push(-x),size++;}
	void del(int x){q1.push(-x),size--;}
	void update(){while(!q1.empty()){if(q0.top()==q1.top()) q0.pop(),q1.pop();else break;}}
};
int n,nn,m,qaq;
struct segtree
{
	int v[N<<2];
	void edit(int x,int w,int px=1,int pl=1,int pr=nn)
	{
		if(pl==pr){v[px]=w;return;}
		int pm=pl+pr>>1;
		if(x<=pm) edit(x,w,px<<1,pl,pm);
		else edit(x,w,px<<1|1,pm+1,pr);
		v[px]=min(v[px<<1],v[px<<1|1]);
	}
	int query(int l,int r,int px=1,int pl=1,int pr=nn)
	{
		if(l<=pl&&r>=pr) return v[px];
		int ret=1145149961;
		int pm=pl+pr>>1;
		if(l<=pm) ret=min(ret,query(l,r,px<<1,pl,pm));
		if(r>pm) ret=min(ret,query(l,r,px<<1|1,pm+1,pr));
		return ret;
	}
};
struct sumireko{int to,ne;};
int w[N];
int dfn[N],low[N],da;
int sta[N],stp;
int fa[N],dep[N],sz[N],dson[N],top[N],id[N];
superheap heap[N];
segtree sgt;
struct graph
{
	sumireko e[N<<1];
	int he[N],ecnt;
	void addline(int f,int t){e[++ecnt].to=t;e[ecnt].ne=he[f],he[f]=ecnt;}
	void tj(int x,graph *g)
	{
		dfn[x]=low[x]=++da,sta[++stp]=x;
		for(int i=he[x],t=e[i].to;i;i=e[i].ne,t=e[i].to)
		{
			if(!dfn[t])
			{
				tj(t,g),low[x]=min(low[x],low[t]);
				if(low[t]>=dfn[x])
				{
					nn++;int px=0;
					while(px!=t)
					{
						px=sta[stp--];
						g->addline(px,nn),g->addline(nn,px);
					}
					g->addline(x,nn),g->addline(nn,x);
				}
			}else low[x]=min(low[x],dfn[t]);
		}
	}
	void dfs(int x)
	{
		sz[x]=1;
		for(int i=he[x],t=e[i].to;i;i=e[i].ne,t=e[i].to)if(t!=fa[x])
		{
			fa[t]=x,dep[t]=dep[x]+1,dfs(t),sz[x]+=sz[t];
			if(x>n) heap[x].push(w[t]);
			if(sz[t]>sz[dson[x]]) dson[x]=t;
		}
	}
	void dfs(int x,int tp)
	{
		if(x>n) w[x]=heap[x].top();
		top[x]=tp,id[x]=++da,sgt.edit(id[x],w[x]);
		if(dson[x]) dfs(dson[x],tp);
		for(int i=he[x],t=e[i].to;i;i=e[i].ne,t=e[i].to)if(t!=fa[x]&&t!=dson[x])
			dfs(t,t);
	}
}g1,g2;
void getans(int x,int y)
{
	int ans=1145149961;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ans=min(ans,sgt.query(id[top[x]],id[x]));
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	ans=min(ans,sgt.query(id[x],id[y]));
	if(x>n) ans=min(ans,w[fa[x]]);
	printf("%d\n",ans);
}
char op[5];
int Iris()
{
	read(n),read(m),read(qaq),nn=n;
	for(int i=1;i<=n;i++) read(w[i]);
	for(int i=1,x,y;i<=m;i++) read(x),read(y),g1.addline(x,y),g1.addline(y,x);
	g1.tj(1,&g2);
	g2.dfs(1),da=0,g2.dfs(1,1);
	for(int rkk=1,x,y;rkk<=qaq;rkk++)
	{
		scanf("%s",op),read(x),read(y);
		switch(op[0])
		{
		case 'A':
			getans(x,y);
			break;
		case 'C':
			sgt.edit(id[x],y);
			if(fa[x])
			{
				int px=fa[x];
				heap[px].del(w[x]);
				heap[px].push(y);
				if(heap[px].top()!=w[px])
				{
					sgt.edit(id[px],heap[px].top());
					w[px]=heap[px].top();
				}
			}
			w[x]=y;
			break;
		}
	}
	return 0;
}
}
int main(){return RKK::Iris();}
CF487E Tourists(圆方树+树链剖分+multiset/可删堆)的更多相关文章
- CF487E Tourists 圆方树、树链剖分
		传送门 注意到我们需要求的是两点之间所有简单路径中最小值的最小值,那么对于一个点双联通分量来说,如果要经过它,则一定会经过这个点双联通分量里权值最小的点 注意:这里不能缩边双联通分量,样例\(2\)就 ... 
- CF487E Tourists + 圆方树学习笔记(圆方树+树剖+线段树+multiset)
		QWQ果然我已经什么都学不会的人了. 这个题目要求的是图上所有路径的点权和!QWQ(我只会树上啊!) 这个如果是好啊 这时候就需要 圆方树! 首先在介绍圆方树之前,我们先来一点简单的前置知识 首先,我 ... 
- CF487E Tourists[圆方树+树剖(线段树套set)]
		做这题的时候有点怂..基本已经想到正解了..结果感觉做法有点假,还是看了正解题解.. 首先提到简单路径上经过的点,就想到了一个关于点双的结论:两点间简单路径上所有可能经过的点的并等于路径上所有点所在点 ... 
- uoj30【CF Round #278】Tourists(圆方树+树链剖分+可删除堆)
		- 学习了一波圆方树 学习了一波点分治 学习了一波可删除堆(巧用 ? STL) 传送门: Icefox_zhx 注意看代码看怎么构建圆方树的. tips:tips:tips:圆方树内存记得开两倍 CO ... 
- Tourists——圆方树
		CF487E Tourists 一般图,带修求所有简单路径代价. 简单路径,不能经过同一个点两次,那么每个V-DCC出去就不能再回来了. 所以可以圆方树,然后方点维护一下V-DCC内的最小值. 那么, ... 
- 线段树&数链剖分
		傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ... 
- bzoj4336 骑士的旅行 (树链剖分+multiset)
		首先大概有一个树剖+树套树的做法,但我哪会写啊 然后发现k很小,如果用线段树记每个区间前k大的的话,可以O(k)地合并 而且一个点还有可能有好多个骑士,所以要用multiset维护一下 然后树剖就好啦 ... 
- CF487E Tourists - Tarjan缩点 + 树剖 + multiset
		Solution 先Tarjan求出点双联通分量 并缩点. 用$multiset$维护 点双内的最小点权. 容易发现, 点双内的最小点权必须包括与它相连的割边的点权. 所以我们必须想办法来维护. 所以 ... 
- [HNOI2016]网络 [树链剖分,可删除堆]
		考虑在 |不在| 这条链上的所有点上放上一个 \(x\),删除也是,然后用可删除堆就随便草掉了. // powered by c++11 // by Isaunoya #pragma GCC opti ... 
随机推荐
- 基于双TMS320C6678 + XC7K420T的6U CPCI Express高速数据处理平台
			1.板卡概述 板卡由我公司自主研发,基于6UCPCI架构,处理板包含双片TI DSP TMS320C6678芯片:一片Xilinx公司FPGA XC7K420T-1FFG1156 芯片:六个千兆网口( ... 
- Solution -「CF 923E」Perpetual Subtraction
			\(\mathcal{Description}\) Link. 有一个整数 \(x\in[0,n]\),初始时以 \(p_i\) 的概率取值 \(i\).进行 \(m\) 轮变换,每次均匀随机 ... 
- python3监控网站状态
			前面已经写过Python3发邮件,Python发微信的文章了.直接导入即可. import configparser,requests from time import sleep import We ... 
- 攻防世界-Crypto高手进阶区部分Writeup
			1.flag_in_your_hand && flag_in_your_hand1 下载,解压后 打开index文件,直接点击get flag错误,输入其他点击也同样 打开js文件,在 ... 
- DNS中的SOA
			起始授权机构,SOA(Start Of Authority):该记录表明DNS名称服务器是DNS域中的数据表的信息来源,该服务器是主机名字的管理者,创建新区域时,该资源记录自动创建,且是DNS数据库文 ... 
- [题解]Mail.Ru Cup 2018 Round 1 - C. Candies Distribution
			[题目] C. Candies Distribution [描述] n个小朋友排排坐吃糖糖,小朋友从左到右编号1到n.每个小朋友手上有一定数量的糖.对于第i个小朋友来说,编号比他小的小朋友中有li个小 ... 
- Renix绑定流详解——网络测试仪实操
			一.测试环境 使用测试仪模拟两台主机直接发流,中间有路由器.如下图,测试仪port1端口模拟的主机IP为10.1.1.2,port2端口模拟的主机IP为10.2.1.2 二.预约测试资源 打开Reni ... 
- 【C#单元测试】 开篇
			官方:https://docs.microsoft.com/zh-cn/visualstudio/test/install-third-party-unit-test-frameworks?view= ... 
- 决策树CART回归树——算法实现
			决策树模型 选择最好的特征和特征的值进行数据集划分 根据上面获得的结果创建决策树 根据测试数据进行剪枝(默认没有数据的树分支被剪掉) 对输入进行预测 模型树 import numpy as np de ... 
- .NET 6 在小并发下如何生成唯一单据号
			一.场景介绍 小并发下要解决生成单据号的问题,会碰到哪些问题呢?,接下来让我们一探究竟[这是小并发的解决方案,大家有更好的做好可以一起讨论分享]. 之所以叫小并发:是因为确实是小并发场景的应用模式,一 ... 
