本题要求我们支持三种操作:

① 点向点连边。 ② 点向区间连边。 ③ 区间向点连边。

然后跑最短路得出答案。

考虑使用线段树优化建图。

建两颗线段树,入树和出树,每个节点为一段区间的原节点集合。入树内部为儿子向父亲连有向边,出树内部为父亲连有向边,因为入树和出树的叶子节点都为原图中的点,所以两棵树的对应叶子节点连无向边,这些边边权都为\(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】的更多相关文章

  1. [题解] CF786B Legacy

    前言 题目链接 题意 有 \(n\) 个点,\(q\) 次连边,以及起点 \(s\) .连边具体分三种: \(1\) \(v\) \(u\) \(w\) 从 \(v\) 到 \(u\) 连一条边. \ ...

  2. CF786B Legacy(线段树优化建边)

    模板题CF786B Legacy 先说算法 如果需要有n个点需要建图 给m个需要建边的信息,从单点(或区间内所有点)向一区间所有点连边 如果暴力建图复杂度\(mn^2\) 以单点连向区间为例,在n个点 ...

  3. CF786B Legacy && 线段树优化连边

    线段树优化连边 要求点 \(x\) 向区间 \([L, R]\) 连边, 一次的复杂度上限为 \(O(n)\) 然后弄成线段树的结构 先父子连边边权为 \(0\) 这样连边就只需要连父亲就可以等效于连 ...

  4. CF786B Legacy 线段树优化建图

    问题描述 CF786B LG-CF786B 题解 线段树优化建图 线段树的一个区间结点代表 \([l,r]\) 区间点. 然后建立区间点的时候就在线段树上建边,有效减少点的个数,从而提高时空效率. 优 ...

  5. 线段树优化建图 || CF786B Legacy

    题面:786B - Legacy 代码: #include<cstdio> #include<cstring> #include<iostream> #includ ...

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

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

  7. CF786B Legacy(线段树优化建图)

    嘟嘟嘟 省选Day1T2不仅考了字符串,还考了线段树优化建图.当时不会,现在赶快学一下. 线段树能优化的图就是像这道题一样,一个点像一个区间的点连边,或一个区间像一个点连边.一个个连就是\(O(n ^ ...

  8. CF786B Legacy

    思路 线段树优化建图 基本思想就是要把一个区间连边拆成log个节点连边, 然后一颗入线段树,一颗出线段树,出线段树都由子节点向父节点连边(可以从子区间出发),入线段树从父节点向子节点连边(可以到达子区 ...

  9. 【CF786B】Legacy

    题目大意:初始给定 N 个点,支持三种操作:两点之间连边:一个点与一个连续区间编号的点之间连边:一个连续区间内的点和一个点连边,求执行 N 次操作之后的单源最短路. 题解:学会了线段树优化建图. 发现 ...

随机推荐

  1. Python-17-作用域

    python有一个名为vars的内置函数,它返回变量关联的不可见的字典: >>> x = 1  >>> scope = vars()  >>> s ...

  2. Java解析apk、ipa图标,包名,应用名称,版本号

    参看:http://blog.csdn.net/moyanxuan_1993_2_24/article/details/53612001

  3. TCP实战二(半连接队列、全连接队列)

    TCP实验一我们利用了tcpdump以及Wireshark对TCP三次握手.四次挥手.流量控制做了深入的分析,今天就让我们一同深入理解TCP三次握手中两个重要的结构:半连接队列.全连接队列. 参考文献 ...

  4. 入门大数据---Hbase的SQL中间层_Phoenix

    一.Phoenix简介 Phoenix 是 HBase 的开源 SQL 中间层,它允许你使用标准 JDBC 的方式来操作 HBase 上的数据.在 Phoenix 之前,如果你要访问 HBase,只能 ...

  5. 部署JUnit

    JUnit的简介和使用:http://blog.csdn.net/luanlouis/article/details/37562165 jar包下载地址:http://www.java2s.com/C ...

  6. css与javascript重难点,学前端,基础不好一切白费!

    JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果.通常JavaScript脚本是通过嵌入在HTML中来实现 ...

  7. 关于CSS自文档的思考_css声明式语言式代码注释

    obert C. Martin写的<Clean Code>是我读过的最好的编程书籍之一,若没有读过,推荐你将它加入书单. 注释就意味着代码无法自说明 —— Robert C. Martin ...

  8. 「疫期集训day13」雾天

    我们千里迢迢赶来这里支援协约国----与德军正面交锋的美国士兵 今天考试签到题都没A,失误重大,T1几周前做过的拓扑排序板子都没写,T2失误在没敢调试,对自己信心不足,30分钟写了个DP,几分钟没调出 ...

  9. 点分治模板 POJ 1741

    #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const ...

  10. opencv3.4.9 + armv7 + arm-linux-gnueabihf交叉编译

    使用CMake指定交叉编译链会有很多报错,原因可能是其找交叉编译的库或这头文件会自动链接到本地的库或者头文件. 可以使用Qt设置好交叉编译环境后,将CMakeLists.txt文件放入,直接编译通过即 ...