← Home
For problem statement at 1000-1999/1300-1399/1350-1359/1359/problemF.txt this is a correct solution, but verifier at 1000-1999/1300-1399/1350-1359/1359/verifierF.go ends with All tests passed can you fix the verifier? package main

import (
	"bufio"
	"fmt"
	"io"
	"math"
	"os"
	"sort"
)

type Event struct {
	x   float64
	y   float64
	typ int
	id  int
}

var (
	n        int
	x0       []float64
	y0       []float64
	vx       []float64
	vy       []float64
	slope    []float64
	lx       []float64
	ly       []float64
	rx       []float64
	events   []Event
	leftCh   []int
	rightCh  []int
	parent   []int
	prio     []uint64
	root     int
	currentX float64
)

func yAt(seg int, x float64) float64 {
	return math.FMA(x-lx[seg], slope[seg], ly[seg])
}

func lessSeg(a, b int) bool {
	ya := yAt(a, currentX)
	yb := yAt(b, currentX)
	if ya < yb {
		return true
	}
	if ya > yb {
		return false
	}
	if slope[a] < slope[b] {
		return true
	}
	if slope[a] > slope[b] {
		return false
	}
	return a < b
}

func eps2(a, b float64) float64 {
	s := math.Abs(a)
	t := math.Abs(b)
	if t > s {
		s = t
	}
	if s < 1 {
		s = 1
	}
	return 1e-9 + 1e-16*s
}

func segIntersect(a, b int) bool {
	l := lx[a]
	if lx[b] > l {
		l = lx[b]
	}
	r := rx[a]
	if rx[b] < r {
		r = rx[b]
	}
	if l > r+eps2(l, r) {
		return false
	}
	yaL := yAt(a, l)
	ybL := yAt(b, l)
	dl := yaL - ybL
	if math.Abs(dl) <= eps2(yaL, ybL) {
		return true
	}
	yaR := yAt(a, r)
	ybR := yAt(b, r)
	dr := yaR - ybR
	if math.Abs(dr) <= eps2(yaR, ybR) {
		return true
	}
	return (dl < 0 && dr > 0) || (dl > 0 && dr < 0)
}

func rotateLeft(x int) {
	y := rightCh[x]
	p := parent[x]
	b := leftCh[y]

	rightCh[x] = b
	if b != 0 {
		parent[b] = x
	}

	leftCh[y] = x
	parent[x] = y
	parent[y] = p

	if p == 0 {
		root = y
	} else if leftCh[p] == x {
		leftCh[p] = y
	} else {
		rightCh[p] = y
	}
}

func rotateRight(x int) {
	y := leftCh[x]
	p := parent[x]
	b := rightCh[y]

	leftCh[x] = b
	if b != 0 {
		parent[b] = x
	}

	rightCh[y] = x
	parent[x] = y
	parent[y] = p

	if p == 0 {
		root = y
	} else if leftCh[p] == x {
		leftCh[p] = y
	} else {
		rightCh[p] = y
	}
}

func findPredSucc(seg int) (int, int) {
	pred, succ := 0, 0
	cur := root
	for cur != 0 {
		cseg := cur - 1
		if lessSeg(seg, cseg) {
			succ = cur
			cur = leftCh[cur]
		} else {
			pred = cur
			cur = rightCh[cur]
		}
	}
	return pred, succ
}

func insertNode(node int) {
	leftCh[node], rightCh[node], parent[node] = 0, 0, 0
	if root == 0 {
		root = node
		return
	}
	cur := root
	for {
		if lessSeg(node-1, cur-1) {
			if leftCh[cur] == 0 {
				leftCh[cur] = node
				parent[node] = cur
				break
			}
			cur = leftCh[cur]
		} else {
			if rightCh[cur] == 0 {
				rightCh[cur] = node
				parent[node] = cur
				break
			}
			cur = rightCh[cur]
		}
	}
	for parent[node] != 0 && prio[node] > prio[parent[node]] {
		p := parent[node]
		if leftCh[p] == node {
			rotateRight(p)
		} else {
			rotateLeft(p)
		}
	}
}

func prevNode(x int) int {
	if leftCh[x] != 0 {
		x = leftCh[x]
		for rightCh[x] != 0 {
			x = rightCh[x]
		}
		return x
	}
	p := parent[x]
	for p != 0 && leftCh[p] == x {
		x = p
		p = parent[p]
	}
	return p
}

func nextNode(x int) int {
	if rightCh[x] != 0 {
		x = rightCh[x]
		for leftCh[x] != 0 {
			x = leftCh[x]
		}
		return x
	}
	p := parent[x]
	for p != 0 && rightCh[p] == x {
		x = p
		p = parent[p]
	}
	return p
}

func eraseNode(node int) {
	for leftCh[node] != 0 || rightCh[node] != 0 {
		if leftCh[node] == 0 {
			rotateLeft(node)
		} else if rightCh[node] == 0 {
			rotateRight(node)
		} else if prio[leftCh[node]] > prio[rightCh[node]] {
			rotateRight(node)
		} else {
			rotateLeft(node)
		}
	}
	p := parent[node]
	if p == 0 {
		root = 0
	} else if leftCh[p] == node {
		leftCh[p] = 0
	} else {
		rightCh[p] = 0
	}
	parent[node] = 0
}

func check(T float64) bool {
	for i := 0; i < n; i++ {
		ex := x0[i] + vx[i]*T
		ey := y0[i] + vy[i]*T
		if x0[i] < ex {
			lx[i] = x0[i]
			ly[i] = y0[i]
			rx[i] = ex
			events[2*i] = Event{lx[i], ly[i], 0, i}
			events[2*i+1] = Event{rx[i], ey, 1, i}
		} else {
			lx[i] = ex
			ly[i] = ey
			rx[i] = x0[i]
			events[2*i] = Event{lx[i], ly[i], 0, i}
			events[2*i+1] = Event{rx[i], y0[i], 1, i}
		}
		node := i + 1
		leftCh[node], rightCh[node], parent[node] = 0, 0, 0
	}

	sort.Slice(events, func(i, j int) bool {
		if events[i].x < events[j].x {
			return true
		}
		if events[i].x > events[j].x {
			return false
		}
		if events[i].typ < events[j].typ {
			return true
		}
		if events[i].typ > events[j].typ {
			return false
		}
		if events[i].y < events[j].y {
			return true
		}
		if events[i].y > events[j].y {
			return false
		}
		return events[i].id < events[j].id
	})

	root = 0
	for _, e := range events {
		currentX = e.x
		node := e.id + 1
		if e.typ == 0 {
			pred, succ := findPredSucc(e.id)
			if pred != 0 && segIntersect(pred-1, e.id) {
				return true
			}
			if succ != 0 && segIntersect(e.id, succ-1) {
				return true
			}
			insertNode(node)
		} else {
			pred := prevNode(node)
			succ := nextNode(node)
			if pred != 0 && succ != 0 && segIntersect(pred-1, succ-1) {
				return true
			}
			eraseNode(node)
		}
	}
	return false
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	idx := 0
	nextInt := func() int {
		for idx < len(data) && (data[idx] == ' ' || data[idx] == '\n' || data[idx] == '\r' || data[idx] == '\t') {
			idx++
		}
		sign := 1
		if data[idx] == '-' {
			sign = -1
			idx++
		}
		val := 0
		for idx < len(data) && data[idx] >= '0' && data[idx] <= '9' {
			val = val*10 + int(data[idx]-'0')
			idx++
		}
		return sign * val
	}

	n = nextInt()
	if n < 2 {
		w := bufio.NewWriterSize(os.Stdout, 1<<20)
		fmt.Fprintln(w, "No show :(")
		w.Flush()
		return
	}

	x0 = make([]float64, n)
	y0 = make([]float64, n)
	vx = make([]float64, n)
	vy = make([]float64, n)
	slope = make([]float64, n)
	lx = make([]float64, n)
	ly = make([]float64, n)
	rx = make([]float64, n)
	events = make([]Event, 2*n)
	leftCh = make([]int, n+1)
	rightCh = make([]int, n+1)
	parent = make([]int, n+1)
	prio = make([]uint64, n+1)

	var seed uint64 = 88172645463393265
	nextRand := func() uint64 {
		seed ^= seed << 7
		seed ^= seed >> 9
		return seed
	}
	for i := 1; i <= n; i++ {
		prio[i] = nextRand()
	}

	for i := 0; i < n; i++ {
		xi := nextInt()
		yi := nextInt()
		dxi := nextInt()
		dyi := nextInt()
		si := nextInt()

		x0[i] = float64(xi)
		y0[i] = float64(yi)
		len := math.Hypot(float64(dxi), float64(dyi))
		f := float64(si) / len
		vx[i] = float64(dxi) * f
		vy[i] = float64(dyi) * f
		slope[i] = float64(dyi) / float64(dxi)
	}

	hi := 6e9
	if !check(hi) {
		w := bufio.NewWriterSize(os.Stdout, 1<<20)
		fmt.Fprintln(w, "No show :(")
		w.Flush()
		return
	}

	lo := 0.0
	for it := 0; it < 80; it++ {
		mid := (lo + hi) * 0.5
		if check(mid) {
			hi = mid
		} else {
			lo = mid
		}
	}

	w := bufio.NewWriterSize(os.Stdout, 1<<20)
	fmt.Fprintf(w, "%.10f\n", hi)
	w.Flush()
}