For problem statement at 0-999/800-899/880-889/887/problemE.txt this is a correct solution, but verifier at 0-999/800-899/880-889/887/verifierE.go ends with All tests passed can you fix the verifier? package main
import (
"bufio"
"fmt"
"io"
"math"
"math/bits"
"os"
"sort"
)
type Interval struct {
l, r float64
}
type U128 struct {
hi, lo uint64
}
func mul64U(a, b uint64) U128 {
hi, lo := bits.Mul64(a, b)
return U128{hi: hi, lo: lo}
}
func addU(a, b U128) U128 {
lo, c := bits.Add64(a.lo, b.lo, 0)
hi, _ := bits.Add64(a.hi, b.hi, c)
return U128{hi: hi, lo: lo}
}
func subU(a, b U128) U128 {
lo, c := bits.Sub64(a.lo, b.lo, 0)
hi, _ := bits.Sub64(a.hi, b.hi, c)
return U128{hi: hi, lo: lo}
}
func cmpU(a, b U128) int {
if a.hi < b.hi {
return -1
}
if a.hi > b.hi {
return 1
}
if a.lo < b.lo {
return -1
}
if a.lo > b.lo {
return 1
}
return 0
}
func lshiftU(a U128, k uint) U128 {
if k == 0 {
return a
}
if k < 64 {
return U128{
hi: a.hi<<k | a.lo>>(64-k),
lo: a.lo << k,
}
}
if k == 64 {
return U128{hi: a.lo, lo: 0}
}
return U128{hi: a.lo << (k - 64), lo: 0}
}
func u128ToFloat(a U128) float64 {
return math.Ldexp(float64(a.hi), 64) + float64(a.lo)
}
func diffToFloat(a, b U128) float64 {
c := cmpU(a, b)
if c >= 0 {
return u128ToFloat(subU(a, b))
}
return -u128ToFloat(subU(b, a))
}
func absU64(x int64) uint64 {
if x < 0 {
return uint64(-x)
}
return uint64(x)
}
func signedMulToFloat(a, b int64) float64 {
v := u128ToFloat(mul64U(absU64(a), absU64(b)))
if (a < 0) != (b < 0) {
return -v
}
return v
}
func scanSide(arr []Interval) float64 {
if len(arr) == 0 {
return 0
}
sort.Slice(arr, func(i, j int) bool {
if arr[i].l == arr[j].l {
return arr[i].r < arr[j].r
}
return arr[i].l < arr[j].l
})
x := 0.0
for _, in := range arr {
if in.l >= x {
break
}
if in.r <= x {
continue
}
x = in.r
}
return x
}
type FastScanner struct {
data []byte
idx int
n int
}
func NewFastScanner() *FastScanner {
data, _ := io.ReadAll(os.Stdin)
return &FastScanner{data: data, n: len(data)}
}
func (fs *FastScanner) NextInt64() int64 {
for fs.idx < fs.n {
c := fs.data[fs.idx]
if c == '-' || (c >= '0' && c <= '9') {
break
}
fs.idx++
}
sign := int64(1)
if fs.data[fs.idx] == '-' {
sign = -1
fs.idx++
}
var v int64
for fs.idx < fs.n {
c := fs.data[fs.idx]
if c < '0' || c > '9' {
break
}
v = v*10 + int64(c-'0')
fs.idx++
}
return sign * v
}
func main() {
fs := NewFastScanner()
x1 := fs.NextInt64()
y1 := fs.NextInt64()
x2 := fs.NextInt64()
y2 := fs.NextInt64()
n := int(fs.NextInt64())
dx := x2 - x1
dy := y2 - y1
D := dx*dx + dy*dy
sqrtD := math.Sqrt(float64(D))
intervals := make([]Interval, 0, n)
for i := 0; i < n; i++ {
cx := fs.NextInt64()
cy := fs.NextInt64()
r := fs.NextInt64()
cross := dx*(cy-y1) - dy*(cx-x1)
mdx := 2*cx - x1 - x2
mdy := 2*cy - y1 - y2
z := mdx*mdx + mdy*mdy - D - 4*r*r
rr := uint64(r * r)
rrD := mul64U(rr, uint64(D))
cross2 := mul64U(absU64(cross), absU64(cross))
N := subU(cross2, rrD)
Nf := u128ToFloat(N)
alpha := 4.0 * Nf
beta := -signedMulToFloat(z, cross)
z2 := mul64U(absU64(z), absU64(z))
z2f := u128ToFloat(z2)
Gf := diffToFloat(z2, lshiftU(rrD, 4)) / 16.0
sqrtDisc := float64(r) * sqrtD * math.Sqrt(z2f+16.0*Nf)
qv := -0.5 * (beta + math.Copysign(sqrtDisc, beta))
s1 := qv / alpha
s2 := Gf / qv
if s1 > s2 {
s1, s2 = s2, s1
}
intervals = append(intervals, Interval{l: s1, r: s2})
}
right := scanSide(intervals)
for i := range intervals {
intervals[i] = Interval{l: -intervals[i].r, r: -intervals[i].l}
}
left := scanSide(intervals)
best := right
if left < best {
best = left
}
ans := sqrtD * math.Sqrt(0.25+best*best)
w := bufio.NewWriterSize(os.Stdout, 1<<20)
fmt.Fprintf(w, "%.15f\n", ans)
w.Flush()
}