Legacy (线段树优化建图)
题目链接:Legacy - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题解:
考虑题目中一个点向区间连边,如真的对区间中的每一点分别连边后跑最短路,时间空间都要炸。
因为是一个点向区间连边,考虑线段树。
1到n构造两颗区间线段数
观察上图(从网上搬的)
两颗线段树,一颗入树父亲向儿子连边,用来优化指向叶子的边(左边的树)一颗出树儿子向父亲连边用来优化从叶子指出的点(右边的树)两棵树完全相同。
每个叶子为表示一个星球(可以理解为拆点处理入边和出边),对应的星球之间连一条边,边权为0,因为一个点到自己不花费代价(图中黄色的边)
对于题中给出的操作,操作一可以与操作二等价(也可以与操作三等价)理解为一个点可以去一个区间。
操作二从第二个树上的叶子v向第一颗树上对应的区间连边(与线段树操作相同)
操作三从第一个树上的叶子v向第二颗颗树上对应的区间连边(与上图不太相同,可以自己画图理解)
最后从s点跑最短路
#include <bits/stdc++.h>
using namespace std;
const int N=5e5+10;
const int M=4e6+10;
#define int long long//数据比较大,会爆int
int tot,n,q,s,cnt,root,nxt[M],go[M],hd[M],dx[M],vis[M],dis[M],jz[M],ans,mi,mx;
void add(int x,int y,int w)
{
nxt[++tot]=hd[x],go[tot]=y,jz[tot]=w,hd[x]=tot;
return ;
}
void build(int x,int l,int r,int lx,int lim)//用lim将第一颗树和第二棵树一起处理
{
if(l==r)
{
x=x+lim;
if(x>mx)mx=x;
dx[++cnt]=x;
return ;
}
int mid=(l+r)>>1;
if(lx==1)add(x+lim,x*2+lim,0),add(x+lim,x*2+1+lim,0);
if(lx==2)add(x*2+lim,x+lim,0),add(x*2+1+lim,x+lim,0);
build(x*2,l,mid,lx,lim);
build(x*2+1,mid+1,r,lx,lim);
}
void search(int x,int l,int r,int lt,int rt,int v,int w,int lx)
{
if(lt<=l&&rt>=r)
{
if(lx==1)add(v,x,w);
else add(x+root-1,v,w);
return ;
}
int mid=(l+r)>>1;
if(lt<=mid)search(x*2,l,mid,lt,rt,v,w,lx);
if(rt>mid)search(x*2+1,mid+1,r,lt,rt,v,w,lx);
return ;
}
struct node
{
int id,zhi;
bool operator<(const node& a)const {return zhi>a.zhi;}
node(int x,int y){id=x,zhi=y;}
};
void dij(int x)
{
memset(dis,0x7f,sizeof(dis));
priority_queue<node> q;
dis[x]=0;
q.push(node(x,0));
while(!q.empty())
{
int u=q.top().id;q.pop();
if(vis[u])continue;
vis[u]=1;
for(int i=hd[u];i;i=nxt[i])
{
int v=go[i];
if(dis[v]>dis[u]+jz[i])
{
dis[v]=dis[u]+jz[i];
if(!vis[v])q.push(node(v,dis[v]));
}
}
}
return ;
}
signed main()
{
scanf("%lld%lld%lld",&n,&q,&s);
build(1,1,n,1,0);
root=mx+1;//第二颗树的root
build(1,1,n,2,mx);//从第二棵树的点表示为mx+1,mx+2,mx+3而不是mx,2*mx,2*mx+1节约空间不然会MLE。
mx=0,mi=1e9;
for(int i=1;i*2<=cnt;i++)//dx存叶子,考虑线段树过程以及两颗线段树相同,可以得出第i(i<=cnt/2)或i-cnt/2(i>cnt/2)个的对应线段树节点为i,
{
if(dx[i]>mx)mx=dx[i];
if(dx[i]<mi)mi=dx[i];
add(dx[i],dx[i+cnt/2],0);
add(dx[i+cnt/2],dx[i],0);//黄色边,即自己向自己连边
}
for(int i=1;i<=q;i++)
{
int lx,l,r,v,w;;scanf("%lld",&lx);
if(lx==1)
{
scanf("%lld%lld%lld",&v,&l,&w);r=l;
search(1,1,n,l,r,dx[v+cnt/2],w,1);
}
if(lx==2)
{
scanf("%lld%lld%lld%lld",&v,&l,&r,&w);
search(1,1,n,l,r,dx[v+cnt/2],w,1);
}
if(lx==3)
{
scanf("%lld%lld%lld%lld",&v,&l,&r,&w);
search(1,1,n,l,r,dx[v],w,2);
}
}
dij(dx[s]);//最短路
for(int i=1;i<=n;i++)
{
if(dis[dx[i]]==9187201950435737471) dis[dx[i]]=-1;//特殊处理不连通
printf("%lld ",dis[dx[i]]);dis存的是线段树节点
}
return 0;
}
别人的建图
void build(int p,int l,int r){
if(l==r){a[l]=p;return ;}
int mid=(l+r)/2;
add(p,p<<1,0),add(p,p<<1|1,0);
add((p<<1)+K,p+K,0),add((p<<1|1)+K,p+K,0);
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
}
提前计算第一颗树的最大值,计为K.
对于i存i的对应线段树节点。
其他差别不大
Legacy (线段树优化建图)的更多相关文章
- CF786B Legacy 线段树优化建图 + spfa
CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...
- Codeforces.786B.Legacy(线段树优化建图 最短路Dijkstra)
题目链接 \(Description\) 有\(n\)个点.你有\(Q\)种项目可以选择(边都是有向边,每次给定\(t,u,v/lr,w\)): t==1,建一条\(u\to v\)的边,花费\(w\ ...
- G. 神圣的 F2 连接着我们 线段树优化建图+最短路
这个题目和之前写的一个线段树优化建图是一样的. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路 之前这个题目可以相当于一个模板,直接套用就可以了. 不 ...
- BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan
Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...
- 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流
[BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...
- 【ARC069F】Flags 2-sat+线段树优化建图+二分
Description 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input 第一行一个整数 N. 接下来 N 行每行两个整数 xi, ...
- 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序
题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆. 现在 ...
- 【bzoj4699】树上的最短路(树剖+线段树优化建图)
题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...
- 【BZOJ4276】[ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流
[BZOJ4276][ONTAK2015]Bajtman i Okrągły Robin Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2 ...
- 【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra
题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a, ...
随机推荐
- 【Oracle】Oracle数据库多实例安装
需求:因为需要从RAC的多实例迁移至单虚拟机的多实例.因此,简要概述一下,如何安装数据库的多实例. 不管是Oracle 11g还是10g的多实例,其基本思路都是一致的. 1.调用dbca 在root账 ...
- 几种常见Ruby on Rails内置方法介绍
Ruby on Rails是一个功能强大的WEB开发框架,在这里我们将会学到一些经常用到的Ruby on Rails内置方法,帮助大家熟练掌握其应用技巧. Ruby on Rails自动生成文档技巧大 ...
- WEB服务与NGINX(20)- nginx 实现HTTP反向代理功能
目录 1. nginx实现反向代理功能 1.1 nginx代理功能概述 1.2 NGINX实现HTTP反向代理 1.2.1 HTTP反向代理基本功能 1.2.1.1 反向代理配置参数 1.2.1.2 ...
- ios系统的css兼容问题处理和iOS上网页滑动不流畅问题
1.H5网页touch滑动的时候在苹果手机上出现不流畅的问题 -webkit-overflow-scrolling 用来控制元素在移动设备上是否使用滚动回弹效果. 解决办法:给所有网页添加如下样式 b ...
- Atm/抢掠计划——题解
题目描述 样例 6 7 1 2 2 3 3 5 2 4 4 1 2 6 6 5 10 12 8 16 1 5 1 4 4 3 5 6 47 解析 题目明显是最长路,可以用spfa求最长路,但数据范围5 ...
- Java面试题:Spring Bean线程安全?别担心,只要你不写并发代码就好了!
Spring中的Bean是否线程安全取决于Bean的作用域(scope).Spring提供了几种不同的Scope,其中包括Singleton.Prototype.Request.Session.Glo ...
- Vue 渲染模板时怎么保留模板中的HTML 注释呢?
在组件中将 comments 选项设置为 true ...
- TCP协议分析工具TcpEngine V1.2.0使用教程
概述 目前主流的网络数据分析工具主要有两类,一类是http协议分析工具,如fiddler,这类工具擅长对字符串类型协议分析:另一类是原始网络数据包的监听分析,如Wireshark,这类工具擅长分析网络 ...
- 记一次ThreadLocal中的用户信息混乱问题
前言 记录一次开发中遇到的关于 ThreadLocal 问题,场景是数据库表中的操作人总是无缘无故的被更改,排查了几遍代码才发现是 ThreadLocal 没有及时清理导致的. 一.为什么使用 Thr ...
- linux源码编译安装软件原理
目录 一.关于软件包 二.软件编译过程 三.编译安装常用参数 四.源码编译出错的解决思路 五.各种软件安装方法的特点 一.关于软件包 在linux中安装软件是需要安装包的,软件的安装包有各种类型: ...