← Home
For problem statement at 0-999/100-199/120-129/128/problemE.txt this is a correct solution, but verifier at 0-999/100-199/120-129/128/verifierE.go ends with Test 1 failed: expected 12 got 22 can you fix the verifier? package main

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

type Curve struct {
	i        int
	s        int
	id       int
	type_val int
}

type Event struct {
	u     int
	v     int
	theta float64
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n, k int
	if _, err := fmt.Fscan(reader, &n, &k); err != nil {
		return
	}

	x := make([]float64, n)
	y := make([]float64, n)
	r := make([]float64, n)

	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &x[i], &y[i], &r[i])
	}

	curves := make([]Curve, 2*n)
	for i := 0; i < n; i++ {
		curves[2*i] = Curve{i, -1, 2 * i, 1}
		curves[2*i+1] = Curve{i, 1, 2*i + 1, -1}
	}

	var events []Event
	for u := 0; u < 2*n; u++ {
		for v := u + 1; v < 2*n; v++ {
			cu, cv := curves[u], curves[v]
			dx := x[cu.i] - x[cv.i]
			dy := y[cu.i] - y[cv.i]
			D := float64(cv.s)*r[cv.i] - float64(cu.s)*r[cu.i]
			R := math.Hypot(dx, dy)

			if math.Abs(D) <= R && R > 1e-11 {
				phi := math.Atan2(dy, dx)
				ratio := D / R
				if ratio > 1 {
					ratio = 1
				} else if ratio < -1 {
					ratio = -1
				}
				acos := math.Acos(ratio)

				t1 := phi + acos
				for t1 < 0 {
					t1 += math.Pi
				}
				for t1 >= math.Pi {
					t1 -= math.Pi
				}

				t2 := phi - acos
				for t2 < 0 {
					t2 += math.Pi
				}
				for t2 >= math.Pi {
					t2 -= math.Pi
				}

				events = append(events, Event{u, v, t1})
				events = append(events, Event{u, v, t2})
			}
		}
	}

	sort.Slice(events, func(a, b int) bool {
		return events[a].theta < events[b].theta
	})

	f := func(id int, theta float64) float64 {
		c := curves[id]
		return x[c.i]*math.Cos(theta) + y[c.i]*math.Sin(theta) + float64(c.s)*r[c.i]
	}

	df := func(id int, theta float64) float64 {
		c := curves[id]
		return -x[c.i]*math.Sin(theta) + y[c.i]*math.Cos(theta)
	}

	order := make([]int, 2*n)
	for i := 0; i < 2*n; i++ {
		order[i] = i
	}

	sort.Slice(order, func(a, b int) bool {
		u, v := order[a], order[b]
		fu, fv := f(u, 0), f(v, 0)
		if math.Abs(fu-fv) > 1e-11 {
			return fu < fv
		}
		return df(u, 0) < df(v, 0)
	})

	pos := make([]int, 2*n)
	for i, id := range order {
		pos[id] = i
	}

	treeSum := make([]int, 8*n)
	treeMax := make([]int, 8*n)

	var build func(node, l, r int)
	build = func(node, l, r int) {
		if l == r {
			treeSum[node] = curves[order[l]].type_val
			treeMax[node] = max(0, treeSum[node])
			return
		}
		mid := (l + r) / 2
		build(2*node, l, mid)
		build(2*node+1, mid+1, r)
		treeSum[node] = treeSum[2*node] + treeSum[2*node+1]
		treeMax[node] = max(treeMax[2*node], treeSum[2*node]+treeMax[2*node+1])
	}
	build(1, 0, 2*n-1)

	var update func(node, l, r, idx, val int)
	update = func(node, l, r, idx, val int) {
		if l == r {
			treeSum[node] = val
			treeMax[node] = max(0, val)
			return
		}
		mid := (l + r) / 2
		if idx <= mid {
			update(2*node, l, mid, idx, val)
		} else {
			update(2*node+1, mid+1, r, idx, val)
		}
		treeSum[node] = treeSum[2*node] + treeSum[2*node+1]
		treeMax[node] = max(treeMax[2*node], treeSum[2*node]+treeMax[2*node+1])
	}

	M := treeMax[1]

	for i := 0; i < len(events); {
		j := i
		involved := make(map[int]bool)
		for j < len(events) && events[j].theta-events[i].theta < 1e-10 {
			involved[events[j].u] = true
			involved[events[j].v] = true
			j++
		}

		var invList []int
		for id := range involved {
			invList = append(invList, id)
		}

		sort.Slice(invList, func(a, b int) bool {
			return pos[invList[a]] < pos[invList[b]]
		})

		var blocks [][]int
		var curBlock []int
		theta := events[i].theta

		for idx, id := range invList {
			if idx == 0 {
				curBlock = append(curBlock, id)
			} else {
				if math.Abs(f(id, theta)-f(curBlock[0], theta)) < 1e-9 {
					curBlock = append(curBlock, id)
				} else {
					blocks = append(blocks, curBlock)
					curBlock = []int{id}
				}
			}
		}
		if len(curBlock) > 0 {
			blocks = append(blocks, curBlock)
		}

		for _, blk := range blocks {
			if len(blk) <= 1 {
				continue
			}
			minP := pos[blk[0]]
			for _, id := range blk {
				if pos[id] < minP {
					minP = pos[id]
				}
			}

			sort.Slice(blk, func(a, b int) bool {
				return df(blk[a], theta) < df(blk[b], theta)
			})

			for kIdx, id := range blk {
				p := minP + kIdx
				order[p] = id
				pos[id] = p
				update(1, 0, 2*n-1, p, curves[id].type_val)
			}
		}

		if treeMax[1] > M {
			M = treeMax[1]
		}

		i = j
	}

	ans := int64(n) + int64(k)*int64(M) + int64(k)*int64(k-1)/2
	fmt.Println(ans)
}