← Home
```go
package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"os"
)

type Edge struct {
	to int
	w  int64
}

var adj [][]Edge
var dist []int64

const INF int64 = 1e18

type PQItem struct {
	dist int64
	node int
}

type PQ []PQItem

func (p PQ) Len() int { return len(p) }

func (p PQ) Less(i, j int) bool { return p[i].dist < p[j].dist }

func (p PQ) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

func (p *PQ) Push(x interface{}) {
	*p = append(*p, x.(PQItem))
}

func (p *PQ) Pop() interface{} {
	old := *p
	n := len(old)
	x := old[n-1]
	*p = old[0 : n-1]
	return x
}

func buildIn(node, start, end, offset int) {
	if start == end {
		adj[offset+node] = append(adj[offset+node], Edge{start, 0})
		return
	}
	mid := (start + end) / 2
	buildIn(2*node, start, mid, offset)
	buildIn(2*node+1, mid+1, end, offset)
	adj[offset+node] = append(adj[offset+node], Edge{offset + 2*node, 0})
	adj[offset+node] = append(adj[offset+node], Edge{offset + 2*node+1, 0})
}

func buildOut(node, start, end, offset int) {
	if start == end {
		adj[start] = append(adj[start], Edge{offset+node, 0})
		return
	}
	mid := (start + end) / 2
	buildOut(2*node, start, mid, offset)
	buildOut(2*node+1, mid+1, end, offset)
	adj[offset + 2*node] = append(adj[offset + 2*node], Edge{offset+node, 0})
	adj[offset + 2*node+1] = append(adj[offset + 2*node+1], Edge{offset+node, 0})
}

func getCanonical(node, start, end, ql, qr, offset int, cans *[]int) {
	if ql > end || qr < start {
		return
	}
	if ql <= start && end <= qr {
		*cans = append(*cans, offset + node)
		return
	}
	mid := (start + end) / 2
	getCanonical(2*node, start, mid, ql, qr, offset, cans)
	getCanonical(2*node+1, mid+1, end, ql, qr, offset, cans)
}

func main() {
	in := bufio.NewReader(os.Stdin)
	var n, q, s int
	fmt.Fscan(in, &n, &q, &s)
	segsize := 4 * (n + 1)
	inStart := n + 1
	outStart := inStart + segsize
	total := outStart + segsize - 1
	adj = make([][]Edge, total+1)
	dist = make([]int64, total+1)
	for i := range dist {
		dist[i] = INF
	}
	buildIn(1, 1, n, inStart)
	buildOut(1, 1, n, outStart)
	for qi := 0; qi < q; qi++ {
		var t int
		fmt.Fscan(in, &t)
		if t == 1 {
			var v, u int
			var w int64
			fmt.Fscan(in, &v, &u, &w)
			adj[v] = append(adj[v], Edge{u, w})
		} else if t == 2 {
			var v, l, r int
			var w int64
			fmt.Fscan(in, &v, &l, &r, &w)
			var cans []int
			getCanonical(1, 1, n, l, r, inStart, &cans)
			for _, can := range cans {
				adj[v] = append(adj[v], Edge{can, w})
			}
		} else if t == 3 {
			var v, l, r int
			var w int64
			fmt.Fscan(in, &v, &l, &r, &w)
			var cans []int
			getCanonical(1, 1, n, l, r, outStart, &cans)
			for _, can := range cans {
				adj[can] = append(adj[can], Edge{v, w})
			}
		}
	}
	pq := &PQ{}
	heap.Init(pq)
	dist[s] = 0
	heap.Push(pq, PQItem{0, s})
	for pq.Len() > 0 {
		item := heap.Pop(pq).(PQItem)
		u := item.node
		cost := item.dist
		if cost > dist[u] {
			continue
		}
		for _, e := range adj[u] {
			to := e.to
			newd := dist[u] + e.w
			if newd < dist[to] {
				dist[to] = newd
				heap.Push(pq, PQItem{newd, to})
			}
		}
	}
	out := bufio.NewWriter(os.Stdout)
	for i := 1; i <= n; i++ {
		if i > 1 {
			fmt.Fprint(out, " ")
		}
		if dist[i] == INF {
			fmt.Fprint(out, -1)
		} else {
			fmt.Fprint(out, dist[i])
		}
	}
	fmt.Fprintln(out)
	out.Flush()
}
```