[CF787D] legacy
题目
Rick和他的同事们研究出了一种新的有关放射的公式,于是许多坏人就在追赶他们。所以Rick希望在被坏人抓住之前把遗产给Morty。
在他们的宇宙里总共有n颗行星,每颗行星有它自己的编号(编号为1到n)。Rick所在的行星的编号是s(地球),但是他不知道Morty在哪?总所周知,Rick有一门能打开奇妙入口的枪。在这把枪的帮助下,他能打开一扇单向门去往任意一个星球(包括那把枪自己所在的星球),但是这玩意是有限制的,因为Rick用的是这玩意的免费试用版。
一般而言,他不能用这把枪打开任意一扇单向的门。但是有q个套餐在它的官网上售卖。每一次你购买了这个套餐,你就能也仅仅能使用它一次,但是你可以重复购买(如果你觉得需要多次使用的话)。
网站上的套餐有以下三种类型:
1.打开一扇从v到u的门
2.打开一扇从v到[l,r]之间任何一个的门
3.打开一扇从[l,r]到v之间任何一个的门
Rick不知道Morty在哪?但是Unity准备告诉他。于是Rick就要准备好一切。
因为Rick的预算不多,所以他想知道从他的星球出发,到达每一个星球的最少花费是多少,如果到达不了,就输出-1.
$1<=n,q<=10^5,1<=s<=n$
题解
首先,最简单的想法就是逐条添加边,但这样的时间复杂度为$O(nm)$
注意到2,3操作的点都是连续的
所以可以考虑把这些点压成一坨一坨的
如果把它缩在线段树的节点里,那么对于一堆连续的点,最多会压成$O(logn)$个点(感性理解)
也就是说,对于2,3操作,最多只会添加$O(logn)$条边。
例如,对于操作 [2,4] - > 1,构造的图如下

注意图中的编号是线段树节点编号。
如图,我们种两颗线段树,一棵压起点,一棵压终点
但这样我们只能走一次边,所以在原图上在稍作改造

如图,我们添加了两种边
- 黑边:起点线段树子向父连接,终点线段树父向子连接
- 绿边:对应的叶子节点从终点线段树向起点线段树连接
这样,我们就可以直接在这张图上跑最短路了,
起点为s在起点线段树中的点,
记得每个点的dis要在终点树上获取
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
using namespace std;
#define N 400000
#define M 1000000
#define int long long
#define mid ((l+r)>>1)
#define lc id*2,l,mid
#define rc id*2+1,mid+1,r
#define root 1,1,n
#define pr pair<int,int>
vector<pr> vec[M];
int n,cnt;
//获取[l,r]的点在线段树中压出来的点
void find(int id,int l,int r,int tl,int tr,vector<int> &area)
{
if(l>=tl&&r<=tr)
{
area.push_back(id);
return;
}
if(tl<=mid) find(lc,tl,tr,area);
if(tr>mid) find(rc,tl,tr,area);
}
//获取单点在线段树中的编号
int find2(int num)
{
vector<int> v;
find(root,num,num,v);
return v[0];
}
//连接[l1,r1]->[l2,r2],即构造红边
void connect(int l1,int r1,int l2,int r2,int w)
{
vector<int> a,b;
find(root,l1,r1,a);
find(root,l2,r2,b);
cnt++;//新建一个中介节点,当然在这题没有必要
for(int i=0;i<a.size();i++) vec[a[i]].push_back(make_pair(cnt,w));
for(int i=0;i<b.size();i++) vec[cnt].push_back(make_pair(b[i]+N,0));
}
void build(int id,int l,int r,int num)//构造黑边
{
if(l==r) return;
if(!num)
{
vec[id*2].push_back(make_pair(id,0));
vec[id*2+1].push_back(make_pair(id,0));
}
else
{
vec[id+N].push_back(make_pair(id*2+N,0));
vec[id+N].push_back(make_pair(id*2+1+N,0));
}
build(lc,num);
build(rc,num);
}
int s,dis[M],inq[M];
queue<int> q;
void spfa()
{
memset(dis,0x6f,sizeof(dis));
s=find2(s);
dis[s+N]=dis[s]=0;
q.push(s);
while(!q.empty())
{
int now=q.front();
q.pop();
inq[now]=false;
for(int i=0;i<vec[now].size();i++)
{
pr p=vec[now][i];
int t=dis[now]+p.second;
if(t<dis[p.first])
{
dis[p.first]=t;
if(!inq[p.first]) q.push(p.first);
inq[p.first]=true;
}
}
}
}
signed main()
{
//freopen("data.txt","r",stdin);
int q;
cin>>n>>q>>s;
cnt=2*N;
build(root,0);
build(root,N);
for(int i=1;i<=n;i++)//构造绿边
{
vector<int> v;
find(root,i,i,v);
int t=v[0];
vec[t+N].push_back(make_pair(t,0));
}
for(int i=1;i<=q;i++)
{
int type,v,w,l,r,u;
scanf("%lld%lld",&type,&u);
if(type==1)
{
scanf("%lld%lld",&v,&w);
connect(u,u,v,v,w);
}
else
{
scanf("%lld%lld%lld",&l,&r,&w);
if(type==3) connect(l,r,u,u,w);
else connect(u,u,l,r,w);
}
}
spfa();
for(int i=1;i<=n;i++)
{
int t=find2(i);
if(dis[t+N]<0x7fffffffffffff) printf("%lld ", dis[t+N]);
else printf("-1 ");
}
}
[CF787D] legacy的更多相关文章
- CF786B/CF787D Legacy
题目描述: luogu cf cf 题解: 最短路+线段树优化建图. 考虑本题的边是点->点.段->点和点->段,我们可以建线段树然后拆成入点和出点. 入点:儿子->父亲,边权 ...
- [CF787D]遗产(Legacy)-线段树-优化Dijkstra(内含数据生成器)
Problem 遗产 题目大意 给出一个带权有向图,有三种操作: 1.u->v添加一条权值为w的边 2.区间[l,r]->v添加权值为w的边 3.v->区间[l,r]添加权值为w的边 ...
- GeoIP Legacy City数据库安装说明
Here is a brief outline of the steps needed to install GeoIP Legacy City on Linux/Unix. The installa ...
- BIOS设置之UEFI/Legacy BIOS切换图文详解
近几年出现的电脑其中相当一部分都配置了UEFI BIOS,不过大多都默认以Legacy BIOS方式启动.而Win8正式上市后, 所有预装Win8(或Win8.1)的电脑都配置了UEFI BIOS并且 ...
- GPT vs MBR 分区 ,,, Legacy BIOS vs UEFI BIOS
MBR与GPT两种磁盘分区格式的区别 http://itoedr.blog.163.com/blog/static/120284297201378114053240 GPT Partition Tab ...
- Neo4j 两种索引Legacy Index与Schema Index区别
Legacy Indexes 在Neo4j 2.0版本之前,Legacy index被称作indexes.这个索引是通过外部图存储在外的Lucene实现,允许“节点”和“联系”以key:value键值 ...
- How to configure Veritas NetBackup (tm) to write Unified and Legacy log files to a different directory
Problem DOCUMENTATION: How to configure Veritas NetBackup (tm) to write Unified and Legacy log files ...
- [论文笔记] Legacy Application Migration to the Cloud: Practicability and Methodology (SERVICES, 2012)
Quang Hieu Vu, Rasool Asal: Legacy Application Migration to the Cloud: Practicability and Methodolog ...
- 安装win7或win8系统时UEFI和Legacy模式的设置
很多新型号的笔记本或台式机主板都开始支持UEFI模式,比起原来的Legacy启动减少了BIOS自检,加快平台启动,如下图所示Legacy,UEFI启动过程: 安装系统,建议选择Legacy模式,在UE ...
随机推荐
- c语言错题本
()malloc(sizeof()) 在stdlib.h包中
- Java的常用API之包装类简介
包装类 包装类: 基本数据类型,使用起来非常方便,但是没有对应的方法来操作这些基本类型的数据可以使用一个类,把基本类型的数据装起来,在类中定义一些方法,这个类叫做包装类,我们可以使用类中的方法来操作这 ...
- SQL分类之DDL:操作数据库表
DDL:操作数据库表 1.操作数据库:CRUD 1.C(Create):创建 创建数据库: create database 数据库名称 创建数据库,判断不存在,再创建: create database ...
- Queue介绍
美人如斯! 前言 队列是一种先进先出(FIFO)的数据结构,与生活中的排队类似,即先来先被服务,这样的特点决定了其具有一定的优先级含义,可以被用于任务调度等场景.队列模型如图: 图1.队列模型 jav ...
- MOOC python笔记(二)python中的数据类型和基本语句
python数据类型 数字类型 整数(int) 与数学中整数概念一致(数字大小没有限制,这和其他语言不同),整数可正可负,默认情况下,整数采用十进制.其他进制需要增加相应的引导符号. 如果是二进制在前 ...
- Redis高级功能-1、高并发基本概述
1.可能的问题 要将redis运用到工程项目中,只使用一台redis是万万不能的,原因如下: (1)从结构上,单个redis服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力较大. (2 ...
- Kubernetes(k8s)网络插件(CNI)的基准测试对比
Kubernetes是一个伟大的容器"乐队".但它不管理Pod-to-Pod通信的网络.这是容器网络接口(CNI)插件的使命,它是实现容器集群工具(Kubernetes,Mes ...
- python卸载重新安装,一键安装卸载前的所有安装的第三方插件
好多小可爱都有这样一个困扰,python有了一个大版本的更新,我也想更新,但是安装的好多第三方的库可怎么办呀,更新之后再去一个一个的安装,那可就烦死了. 在这里我来教大家如何快速去安装python更新 ...
- python3 marshmallow学习
python3 marshmallow学习 官方文档:https://marshmallow.readthedocs.io/en/stable/ 安装: pip install -U marshmal ...
- Django---ORM的常用字段和自定义字段,DjangoORM字段与数据库类型对应,字段参数和Meta的参数,Django的admin操作,13中orm操作方法,单标的双下方法
Django---ORM的常用字段和自定义字段,DjangoORM字段与数据库类型对应,字段参数和Meta的参数,Django的admin操作,13中orm操作方法,单标的双下方法 一丶ORM常用字段 ...