题解 CF786B 【Legacy】
本题要求我们支持三种操作:
① 点向点连边。 ② 点向区间连边。 ③ 区间向点连边。
然后跑最短路得出答案。
考虑使用线段树优化建图。
建两颗线段树,入树和出树,每个节点为一段区间的原节点集合。入树内部为儿子向父亲连有向边,出树内部为父亲连有向边,因为入树和出树的叶子节点都为原图中的点,所以两棵树的对应叶子节点连无向边,这些边边权都为\(0\)。
示意图如下,左边为入树,右边为出树。

操作一时,从入树叶子节点向出树叶子节点连边(红色的线)。
操作二时,从入树叶子节点向出树所对应的区间节点连边(蓝色的线)。
操作三时,从入树所对应的区间节点向出树叶子节点连边(绿色的线)。
具体实现细节看代码吧。
记得开\(long\ long\)和开大数组。
\(code:\)
#include<bits/stdc++.h>
#define maxn 800010
#define inf 2000000000
using namespace std;
typedef long long ll;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
int n,m,s,flag;
struct edge
{
int to,nxt,v;
}e[maxn];
int head[maxn],edge_cnt;
void add(int from,int to,int val)
{
e[++edge_cnt]=(edge){to,head[from],val};
head[from]=edge_cnt;
}
int in_root,out_root,tree_cnt;
int ls[maxn],rs[maxn],in_num[maxn],out_num[maxn];
void build_in(int L,int R,int &cur)
{
cur=++tree_cnt;
if(L==R)
{
in_num[L]=cur;
return;
}
int mid=(L+R)>>1;
build_in(L,mid,ls[cur]);
build_in(mid+1,R,rs[cur]);
add(ls[cur],cur,0),add(rs[cur],cur,0);
}
void build_out(int L,int R,int &cur)
{
cur=++tree_cnt;
if(L==R)
{
out_num[L]=cur;
return;
}
int mid=(L+R)>>1;
build_out(L,mid,ls[cur]);
build_out(mid+1,R,rs[cur]);
add(cur,ls[cur],0),add(cur,rs[cur],0);
}
void modify_in(int L,int R,int l,int r,int pos,int val,int &cur)
{
if(L<=l&&R>=r)
{
add(cur,pos,val);
return;
}
int mid=(l+r)>>1;
if(L<=mid) modify_in(L,R,l,mid,pos,val,ls[cur]);
if(R>mid) modify_in(L,R,mid+1,r,pos,val,rs[cur]);
}
void modify_out(int L,int R,int l,int r,int pos,int val,int &cur)
{
if(L<=l&&R>=r)
{
add(pos,cur,val);
return;
}
int mid=(l+r)>>1;
if(L<=mid) modify_out(L,R,l,mid,pos,val,ls[cur]);
if(R>mid) modify_out(L,R,mid+1,r,pos,val,rs[cur]);
}
ll dis[maxn];
bool vis[maxn];
struct node
{
ll val;
int num;
};
bool operator <(const node &x,const node &y)
{
return x.val>y.val;
}
priority_queue<node> q;
void dijkstra()
{
s=in_num[s];
for(int i=1;i<=tree_cnt;++i) dis[i]=inf;
dis[s]=0;
q.push((node){0,s});
while(!q.empty())
{
node tmp=q.top();
q.pop();
int x=tmp.num;
if(vis[x]) continue;
vis[x]=true;
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to,v=e[i].v;
if(dis[y]>dis[x]+v)
{
dis[y]=dis[x]+v;
q.push((node){dis[y],y});
}
}
}
}
int main()
{
read(n),read(m),read(s);
build_in(1,n,in_root);
build_out(1,n,out_root);
for(int i=1;i<=n;++i)
add(in_num[i],out_num[i],0),add(out_num[i],in_num[i],0);
while(m--)
{
read(flag);
int x,y,l,r,v;
if(flag==1)
{
read(x),read(y),read(v);
add(in_num[x],out_num[y],v);
}
if(flag==2)
{
read(x),read(l),read(r),read(v);
modify_out(l,r,1,n,in_num[x],v,out_root);
}
if(flag==3)
{
read(x),read(l),read(r),read(v);
modify_in(l,r,1,n,out_num[x],v,in_root);
}
}
dijkstra();
for(int i=1;i<=n;++i)
{
if(dis[out_num[i]]==inf) printf("-1 ");
else printf("%lld ",dis[out_num[i]]);
}
return 0;
}
题解 CF786B 【Legacy】的更多相关文章
- [题解] CF786B Legacy
前言 题目链接 题意 有 \(n\) 个点,\(q\) 次连边,以及起点 \(s\) .连边具体分三种: \(1\) \(v\) \(u\) \(w\) 从 \(v\) 到 \(u\) 连一条边. \ ...
- CF786B Legacy(线段树优化建边)
模板题CF786B Legacy 先说算法 如果需要有n个点需要建图 给m个需要建边的信息,从单点(或区间内所有点)向一区间所有点连边 如果暴力建图复杂度\(mn^2\) 以单点连向区间为例,在n个点 ...
- CF786B Legacy && 线段树优化连边
线段树优化连边 要求点 \(x\) 向区间 \([L, R]\) 连边, 一次的复杂度上限为 \(O(n)\) 然后弄成线段树的结构 先父子连边边权为 \(0\) 这样连边就只需要连父亲就可以等效于连 ...
- CF786B Legacy 线段树优化建图
问题描述 CF786B LG-CF786B 题解 线段树优化建图 线段树的一个区间结点代表 \([l,r]\) 区间点. 然后建立区间点的时候就在线段树上建边,有效减少点的个数,从而提高时空效率. 优 ...
- 线段树优化建图 || CF786B Legacy
题面:786B - Legacy 代码: #include<cstdio> #include<cstring> #include<iostream> #includ ...
- CF786B Legacy 线段树优化建图 + spfa
CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...
- CF786B Legacy(线段树优化建图)
嘟嘟嘟 省选Day1T2不仅考了字符串,还考了线段树优化建图.当时不会,现在赶快学一下. 线段树能优化的图就是像这道题一样,一个点像一个区间的点连边,或一个区间像一个点连边.一个个连就是\(O(n ^ ...
- CF786B Legacy
思路 线段树优化建图 基本思想就是要把一个区间连边拆成log个节点连边, 然后一颗入线段树,一颗出线段树,出线段树都由子节点向父节点连边(可以从子区间出发),入线段树从父节点向子节点连边(可以到达子区 ...
- 【CF786B】Legacy
题目大意:初始给定 N 个点,支持三种操作:两点之间连边:一个点与一个连续区间编号的点之间连边:一个连续区间内的点和一个点连边,求执行 N 次操作之后的单源最短路. 题解:学会了线段树优化建图. 发现 ...
随机推荐
- 新来的"大神"用策略模式把if else给"优化"了,技术总监说:能不能想好了再改?
本文来自作者投稿,原作者:上帝爱吃苹果 目前在魔都,贝壳找房是我的雇主,平时关注一些 java 领域相关的技术,希望你们能在这篇文章中找到些有用的东西.个人水平有限,如果文章有错误还请指出,在留言区一 ...
- .NET 5.0预览版6发布:支持Windows ARM64设备
2020年6月25日,微软dotnet团队在博客宣布了第六个 .NET 5.0 的预览版:https://devblogs.microsoft.com/dotnet/announcing-net-5- ...
- JavaScript基础数组的字面声名法(010)
1.两种方法的对比 数组在JavaScript中,就像大多数的其它语言 一样,是对象.我们可以使用JavaScript内置的数组构造函数Array()来创建数组.就象对象的字面声名法一样,数组也可以采 ...
- web开发相关概念
什么是web通信? WEB采用B/S通信模式,通过超文本传送协议(HTTP, Hypertext transport protocol)进行通信.通过浏览器地址栏编写URL,向服务器发送一个请求,服务 ...
- 带你学够浪:Go语言基础系列 - 10分钟学方法和接口
文章每周持续更新,原创不易,「三连」让更多人看到是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 对于一般的语言使用者来说 ,20% 的语言特性就能够满 ...
- P3295 萌萌哒 题解
题目 一个长度为n的大数,用\(S_1,S_2,S_3...S_n\)表示,其中\(S_i\)表示数的第\(i\)位,\(S_1\)是数的最高位,告诉你一些限制条件,每个条 件表示为四个数,\(l_1 ...
- BZOJ3573 米特运输 题解
题目 米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储存一直是一个大问题.D星上有N个城市,我们将其顺序编号为1到N,1号城市为首都.这N个城市由 ...
- 一文了解HAProxy主要特性
本文转自Rancher Labs 在Kubernetes中,Ingress对象定义了一些路由规则,这些规则规定如何将一个客户端请求路由到指定服务,该服务运行在你的集群中.这些规则可以考虑到输入的HTT ...
- 16进制字符串转BCD码
15位IMEI字符串转8位BCD码 public static string SwapStr(string str) { return (str.Substring(1, 1) + str.Subst ...
- day78 通过axios实现数据请求
目录 一.axios提供http请求的两个常用方法 二.json 1.json数据的语法 2 js中提供json数据转化的方式 三 ajax 1 数据接口 2 ajax在jq和vue的不同使用 3 同 ...