题目链接: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 (线段树优化建图)的更多相关文章

  1. CF786B Legacy 线段树优化建图 + spfa

    CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...

  2. Codeforces.786B.Legacy(线段树优化建图 最短路Dijkstra)

    题目链接 \(Description\) 有\(n\)个点.你有\(Q\)种项目可以选择(边都是有向边,每次给定\(t,u,v/lr,w\)): t==1,建一条\(u\to v\)的边,花费\(w\ ...

  3. G. 神圣的 F2 连接着我们 线段树优化建图+最短路

    这个题目和之前写的一个线段树优化建图是一样的. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路 之前这个题目可以相当于一个模板,直接套用就可以了. 不 ...

  4. BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan

    Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...

  5. 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流

    [BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...

  6. 【ARC069F】Flags 2-sat+线段树优化建图+二分

    Description ​ 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input ​ 第一行一个整数 N. ​ 接下来 N 行每行两个整数 xi, ...

  7. 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序

    题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆.  现在 ...

  8. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

  9. 【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 ...

  10. 【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra

    题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a, ...

随机推荐

  1. Oracle和达梦:循环执行SQL(如循环插入数据)

    Oracle和达梦:循环执行SQL(如循环插入数据) 其中:WHILE i <= 100000 LOOP,10万是循环10万次 其中:i NUMBER := 1;,1是从一开始 -- 循环执行一 ...

  2. Linux服务器安装GaussDB 100及安装过程中常见问题解决

    ******************************** Gaussdb 100安装 ******************************** 1. 创建安装包目录 mkdir -p ...

  3. 【爬虫GUI】YouTube评论采集软件,突破反爬,可无限爬取!

    目录 一.背景介绍 1.1 软件说明 1.2 效果演示 二.科普知识 2.1 关于视频id 2.2 关于评论时间 三.爬虫代码 3.1 界面模块 3.2 爬虫模块 3.3 日志模块 四.获取源码及软件 ...

  4. axios的基本

    目录 axios基本使用.html axios+vue.html axios基本使用.html <!DOCTYPE html> <html lang="en"&g ...

  5. NVCC编译选项含义解析

    NVCC编译 nvcc 是cuda程序的编译器. 1. 编译阶段 用于指定编译阶段最基本的编译参数. -c: 同gcc,只预处理.编译和汇编为.o文件,不link -lib:生成一个库文件,windo ...

  6. 渐变颜色css设置

    小说付费章节渐变颜色配置 position: absolute; top: 0; left: 0; width: 100%; height: 211px; transform: translateY( ...

  7. ansible自定义模板部署apache服务

    使用Ansible来部署Apache服务是一个很好的选择,因为它可以自动化部署过程,确保所有的服务器上都有相同的配置.以下是一个简单的步骤指南,展示如何使用Ansible来部署Apache服务: 1 ...

  8. pageoffice6在线编辑word 文件禁止鼠标右键

    有时让用户使用PageOffice只读模式(OpenModeType.docReadOnly)打开Word文件后,为了更好的只读效果,还希望禁用Word中的右键菜单,实现此效果只需创建com.zhuo ...

  9. 磁盘空间满了报错cannot create temp file for here-document: No space left on device

    如下:虚拟机设置的存储空间是20G,.目前用到100%了.执行命令会报错设备没有空间 我想删除镜像释放空间,也无法操作 分级找到文件,但是不知道删除哪个 退出的容器都找不到了 把昨天下午弄的删了 容器 ...

  10. Xenocode Postbuild——C#代码混淆器使用方法

    安装 不多作赘述 使用步骤 选择[application]选项卡,选择[add],如果添加的是exe,则[Preset]选择第一项,添加的是dll则选择第二项 选择[Protect]选项卡,将两个都勾 ...