D. Legacy

time limit per test:2 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output

Rick and his co-workers have made a new radioactive formula and a lot of bad guys are after them. So Rick wants to give his legacy to Morty before bad guys catch them.

There are n planets in their universe numbered from 1 to n. Rick is in planet number s (the earth) and he doesn't know where Morty is. As we all know, Rick owns a portal gun. With this gun he can open one-way portal from a planet he is in to any other planet (including that planet). But there are limits on this gun because he's still using its free trial.

By default he can not open any portal by this gun. There are q plans in the website that sells these guns. Every time you purchase a plan you can only use it once but you can purchase it again if you want to use it more.

Plans on the website have three types:

  1. With a plan of this type you can open a portal from planet v to planet u.
  2. With a plan of this type you can open a portal from planet v to any planet with index in range [l, r].
  3. With a plan of this type you can open a portal from any planet with index in range [l, r] to planet v.

Rick doesn't known where Morty is, but Unity is going to inform him and he wants to be prepared for when he finds and start his journey immediately. So for each planet (including earth itself) he wants to know the minimum amount of money he needs to get from earth to that planet.

Input

The first line of input contains three integers nq and s (1 ≤ n, q ≤ 105, 1 ≤ s ≤ n) — number of planets, number of plans and index of earth respectively.

The next q lines contain the plans. Each line starts with a number t, type of that plan (1 ≤ t ≤ 3). If t = 1 then it is followed by three integers vu and w where w is the cost of that plan (1 ≤ v, u ≤ n, 1 ≤ w ≤ 109). Otherwise it is followed by four integers vlr and w where w is the cost of that plan (1 ≤ v ≤ n, 1 ≤ l ≤ r ≤ n, 1 ≤ w ≤ 109).

Output

In the first and only line of output print n integers separated by spaces. i-th of them should be minimum money to get from earth to i-th planet, or  - 1 if it's impossible to get to that planet.

Examples

input

3 5 1
2 3 2 3 17
2 3 2 2 16
2 2 2 3 3
3 3 1 1 12
1 3 3 17

output

0 28 12 

input

4 3 1
3 4 1 3 12
2 2 3 4 10
1 2 4 16

output

0 -1 -1 12 

Note

In the first sample testcase, Rick can purchase 4th plan once and then 2nd plan in order to get to get to planet number 2.

题意:有n个点,q个询问,每次询问有一种操作。操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w;操作2:[l,r]→u的距离为w;操作3:u到v的距离为w;求起点到其他点的最短距离,到达不了输出-1。

思路:这道题目如果老老实实的去建图的话,边会多到爆炸。所以我们需要另外想一个建图方法。

   由于边的起点或者终点涉及到了区间的情况,我们可以使用线段树建图的套路。

   对于整段区间,我们用把它划分成一颗线段树。

   对于整个图,我们可以构造两颗线段树A和B。

   在A线段树上,我们从底部往上连权值为0的边。对于B线段树来说我们从顶部往下连边权值为0的边。

   然后我们把B线段树底部的所有点向A线段树底部的点连权值为0得边。

   对于type=1的边,我们从A线段树底部的点向B线段树底部的点做权值为w的边。

   对于type=2的边,我们从A线段树底部的点向B线段树对应的区间段连权值为w的一些边。

   对于type=3的边,我们从A线段树对应的区间段向B线段树底部对应的点连权值为w的一些边。

   然后跑最短路就行了。

 //2017-09-04
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#define ll long long
#define lson (id<<1)
#define rson ((id<<1)|1) using namespace std; const int N = ;
const ll INF = 0x3f3f3f3f3f3f3f3f; int head[N<<], tot;
struct Edge{
int to, w, next;
}edge[N<<]; void init(){
tot = ;
memset(head, -, sizeof(head));
} void add_edge(int u, int v, int w){
edge[tot].w = w;
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
} vector<int> vec;
int tree[][N<<], idx;
//k为0表示从顶向下的线段树
//k为1表示从底向上的线段树
void build(int id, int l, int r, int k){
tree[k][id] = ++idx;
if(l == r){
if(k == )
add_edge(tree[k][id], l, );
else
add_edge(l, tree[k][id], );
return;
}
int mid = (l+r)>>;
build(lson, l, mid, k);
build(rson, mid+, r, k);
if(k == ){
add_edge(tree[k][id], tree[k][lson], );
add_edge(tree[k][id], tree[k][rson], );
}else{
add_edge(tree[k][lson], tree[k][id], );
add_edge(tree[k][rson], tree[k][id], );
}
} //获得[L, R]区间对应的节点集合
//l,r为辅助变量,k表示操作第k棵线段树
void get_interval(int id, int l, int r, int L, int R, int k){
if(L <= l && r <= R){
vec.push_back(tree[k][id]);
return;
}
int mid = (l+r)>>;
if(mid >= L)
get_interval(lson, l, mid, L, R, k);
if(mid < R)
get_interval(rson, mid+, r, L, R, k);
} bool vis[N<<];
ll dis[N<<];
int cnt[N<<];
deque<int> dq; bool spfa(int s, int n){
memset(vis, , sizeof(vis));
memset(cnt, , sizeof(cnt));
for(int i = ; i <= n; i++)
dis[i] = INF;
vis[s] = ;
dis[s] = ;
cnt[s] = ;
deque<int> dq;
dq.push_back(s);
while(!dq.empty()){
int u = dq.front();
dq.pop_front();
vis[u] = ;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if(dis[v] > dis[u] + edge[i].w){
dis[v] = dis[u] + edge[i].w;
if(!vis[v]){
vis[v] = ;
dq.push_back(v);
if(++cnt[v] > n)return false;
}
}
}
}
return true;
}
int main()
{
//freopen("inputD.txt", "r", stdin);
int n, q, s;
while(scanf("%d%d%d", &n, &q, &s) != EOF){
init();
idx = n;//线段树上表示区间的点从n+1开始
build(, , n, );
build(, , n, );
int l, r, v, w, u, t;
while(q--){
scanf("%d", &t);
if(t == ){
scanf("%d%d%d", &v, &u, &w);
add_edge(v, u, w);
}else if(t == ){
scanf("%d%d%d%d", &v, &l, &r, &w);
vec.clear();
get_interval(, , n, l, r, );
for(auto &u : vec)
add_edge(v, u, w);
}else if(t == ){
scanf("%d%d%d%d", &v, &l, &r, &w);
vec.clear();
get_interval(, , n, l, r, );
for(auto &u : vec)
add_edge(u, v, w);
}
}
spfa(s, *n);
for(int i = ; i <= n; i++)
if(dis[i] == INF)
printf("-1 ");
else printf("%I64d ", dis[i]);
printf("\n");
} return ;
}

Codeforces787D(SummerTrainingDay06-D 线段树+最短路)的更多相关文章

  1. Vijos 1404 遭遇战 - 动态规划 - 线段树 - 最短路 - 堆

    背景 你知道吗,SQ Class的人都很喜欢打CS.(不知道CS是什么的人不用参加这次比赛). 描述 今天,他们在打一张叫DUSTII的地图,万恶的恐怖分子要炸掉藏在A区的SQC论坛服务器!我们SQC ...

  2. Codeforces 787D Legacy 线段树 最短路

    题意: 有\(n(1 \leq n \leq 10^5)\)个点,\(q(1 \leq q \leq 10^5)\)条路和起点\(s\) 路有三种类型: 从点\(v\)到点\(u\)需要花费\(w\) ...

  3. 786B - Legacy(线段树 + 最短路)线段树优化建图

    题意: 就是给定一张n nn个点的图,求源点s ss到每个点的单源最短路.这张图共有q组边,连边方式有3种: a→b ,边权为w的单向边:a→[l,r] ,即a到连续区间[l,r]中的每一个点都有一条 ...

  4. HDU5361 In Touch(线段树 + 最短路)

    传送门 恰逢才做过VFK的A+B Problem,发现这道题也可以那样搞.区间连边的时候,我们就可以给那个区间在线段树对应的标号上连边. 线段树也可以不建出来,直接当做一个标号的合集,不占用内存,只用 ...

  5. CodeForces786B 线段树 + 最短路

    给定n颗行星,q次处理,地球位置为s,求解在q次处理后,地球到每一颗行星的位置. 其中q有三种不同的操作: 输入v,u,wv,u,w,构建一条从vv到uu的代价为ww的路线 输入u,l,r,wu,l, ...

  6. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路

    B - Legacy CodeForces - 787D 这个题目开始看过去还是很简单的,就是一个最短路,但是这个最短路的建图没有那么简单,因为直接的普通建图边太多了,肯定会超时的,所以要用线段树来优 ...

  7. HDU 5669 线段树优化建图+分层图最短路

    用线段树维护建图,即把用线段树把每个区间都标号了,Tree1中子节点有到达父节点的单向边,Tree2中父节点有到达子节点的单向边. 每次将源插入Tree1,汇插入Tree2,中间用临时节点相连.那么T ...

  8. HDU5669 Road 分层最短路+线段树建图

    分析:(官方题解) 首先考虑暴力,显然可以直接每次O(n^2) ​的连边,最后跑一次分层图最短路就行了. 然后我们考虑优化一下这个连边的过程 ,因为都是区间上的操作,所以能够很明显的想到利用线段树来维 ...

  9. 最短路 BZOJ3694 树链剖分+线段树

    分析: 树剖裸题,[Usaco2009 Jan]安全路经Travel 的简化版 剖开最短路树,遍历每一条没在最短路树上的边. 这种情况下,有且仅有u到v路径上,出来lca之外的点能够通过这条边到达,并 ...

随机推荐

  1. file_put_contents 换行

    file_put_contents('test.text', json_encode($result) . PHP_EOL, FILE_APPEND);

  2. Linux学习笔记-基本操作2

    1. 压缩包管理2. 进程管理3. 网路管理4. ftp服务器搭建5. nfs服务器搭建6. ssh服务器7. scp命令8. 其他命令9. 关机重启 1. 压缩包管理 1>. 屌丝版:不能对目 ...

  3. Python做web开发,推荐几个能立马上手的小项目

    Python这门优美的语言是非常适合web开发的,基于Python的Django框架简单便捷且很强大. 那么作为新手该如何上手这门语言?一切不敲代码的学编程手段都是扯淡,今天就推荐一些适合新手练手的P ...

  4. [每天解决一问题系列 - 0004] Excel 公式中拼接字符串

    问题描述: 之前很少用excel的formula,今天用户发过来一个文件,里边存储了很多字段对应的编号.想把这些生成我想要的格式,然后导入代码中,当然可以使用第三方的excel操作库来做.最简单直接的 ...

  5. 线程中的定时器Timer类

    Timer 定时器 几分钟之后执行一个任务. 创建了一个定时器相当于开启了一条线程,TimerTask相当于一个线程的任务.内部使用wait/notify机制来实现的. 用法非常的简单  就足以里面的 ...

  6. MySQL笔记(1)---MySQL体系结构和存储引擎

    1.前言 本系列记录MYSQL数据库的一些结构和实现特点,方便查询. 2.基本概念 数据库:物理操作系统文件或者其他形式文件类型的集合.MySQL中数据库文件可以是frm.MYD.MYI.ibd结尾的 ...

  7. Mac下安装Eclipse和Tomcat等

    Mac下做Java开发还是很方便的,不用像.NET开发一样在Parallel Desktop里面安装Windows虚拟机,Mac下面默认已经安装了JDK. 当然,你如果要安装JDK7,请先阅读:htt ...

  8. ThreadPoolExecutor 中的 shutdown() 、 shutdownNow() 、 awaitTermination() 的用法和区别

    Java并发编程中在使用到ThreadPoolExecutor时,对它的三个关闭方法(shutdown().shutdownNow().awaitTermination())的异同点如下: shutd ...

  9. [java初探06]__排序算法的简单认识

    今天,准备填完昨天没填的坑,将排序算法方面的知识系统的学习一下,但是在简单的了解了一下后,有些不知如何组织学习了,因为排序算法的种类,实在是太多了,各有优略,各有适用的场景.有些不知所措,从何开始. ...

  10. linux文件命令汇总

    查看文件内容命令 cat 直接输出在命令行,适用于很少内容时候的输出, vim .vi  通过 编辑命令的只读模式进行文件内容的查看(翻页快捷键好像是 ctrl + F 下一页, ctrl + B 上 ...