← Home
For problem statement at 1000-1999/1800-1899/1840-1849/1841/problemF.txt this is a correct solution, but verifier at 1000-1999/1800-1899/1840-1849/1841/verifierF.go ends with case 1 failed: expected:
117.0000000000
got:
117
input:
5
0 3 3 1
0 4 0 3
1 1 2 3
3 4 0 3
2 3 1 2
exit status 1 can you fix the verifier? ```go
package main

import (
	"bufio"
	"fmt"
	"math/big"
	"os"
	"sort"
)

type Vec struct {
	x, y int64
}

func quad(x, y int64) int {
	if x > 0 && y >= 0 {
		return 1
	}
	if x <= 0 && y > 0 {
		return 2
	}
	if x < 0 && y <= 0 {
		return 3
	}
	if x >= 0 && y < 0 {
		return 4
	}
	return 0
}

type Group struct {
	sumX, sumY int64
	dirX, dirY int64
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1024*1024), 1024*1024)

	nextInt := func() int64 {
		scanner.Scan()
		res := int64(0)
		for _, b := range scanner.Bytes() {
			res = res*10 + int64(b-'0')
		}
		return res
	}

	if !scanner.Scan() {
		return
	}
	n := 0
	for _, b := range scanner.Bytes() {
		n = n*10 + int(b-'0')
	}

	vecs := make([]Vec, 0, n)
	for i := 0; i < n; i++ {
		a := nextInt()
		b := nextInt()
		c := nextInt()
		d := nextInt()
		x := a - b
		y := c - d
		if x == 0 && y == 0 {
			continue
		}
		vecs = append(vecs, Vec{x, y})
	}

	if len(vecs) == 0 {
		fmt.Println(0)
		return
	}

	sort.Slice(vecs, func(i, j int) bool {
		q1 := quad(vecs[i].x, vecs[i].y)
		q2 := quad(vecs[j].x, vecs[j].y)
		if q1 != q2 {
			return q1 < q2
		}
		return vecs[i].x*vecs[j].y-vecs[j].x*vecs[i].y > 0
	})

	var merged []Group
	for _, v := range vecs {
		if len(merged) > 0 {
			last := &merged[len(merged)-1]
			if quad(last.dirX, last.dirY) == quad(v.x, v.y) && last.dirX*v.y-v.x*last.dirY == 0 {
				last.sumX += v.x
				last.sumY += v.y
				continue
			}
		}
		merged = append(merged, Group{sumX: v.x, sumY: v.y, dirX: v.x, dirY: v.y})
	}

	M := len(merged)
	for i := 0; i < M; i++ {
		merged = append(merged, merged[i])
	}

	prefX := make([]int64, 2*M+1)
	prefY := make([]int64, 2*M+1)
	for i := 0; i < 2*M; i++ {
		prefX[i+1] = prefX[i] + merged[i].sumX
		prefY[i+1] = prefY[i] + merged[i].sumY
	}

	var maxSq big.Int
	var tempX, tempY, sqX, sqY, sq big.Int

	updateMax := func(x, y int64) {
		tempX.SetInt64(x)
		tempY.SetInt64(y)
		sqX.Mul(&tempX, &tempX)
		sqY.Mul(&tempY, &tempY)
		sq.Add(&sqX, &sqY)
		if sq.Cmp(&maxSq) > 0 {
			maxSq.Set(&sq)
		}
	}

	getSum := func(L, R int) (int64, int64) {
		if L > R {
			return 0, 0
		}
		return prefX[R+1] - prefX[L], prefY[R+1] - prefY[L]
	}

	j := 0
	for i := 0; i < M; i++ {
		if j <= i {
			j = i + 1
		}
		for j < i+M {
			cross := merged[i].dirX*merged[j].dirY - merged[j].dirX*merged[i].dirY
			if cross > 0 {
				j++
			} else {
				break
			}
		}

		hasOpp := false
		if j < i+M {
			cross := merged[i].dirX*merged[j].dirY - merged[j].dirX*merged[i].dirY
			if cross == 0 {
				dot := merged[i].dirX*merged[j].dirX + merged[i].dirY*merged[j].dirY
				if dot < 0 {
					hasOpp = true
				}
			}
		}

		x, y := getSum(i+1, j-1)
		updateMax(x, y)

		x, y = getSum(i, j-1)
		updateMax(x, y)

		if hasOpp {
			x, y = getSum(i+1, j)
			updateMax(x, y)

			x, y = getSum(i, j)
			updateMax(x, y)
		}
	}

	fmt.Println(maxSq.String())
}
```