← 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 17 can you fix the verifier? package main

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

const (
	epsAngle    = 1e-12
	epsBoundary = 1e-14
	epsValue    = 1e-10
	twoPi       = 2 * math.Pi
)

type Event struct {
	ang float64
	a   uint16
	b   uint16
}

type Seg struct {
	n    int
	sum  []int
	pref []int
}

func NewSeg(vals []int) *Seg {
	n := 1
	for n < len(vals) {
		n <<= 1
	}
	s := &Seg{
		n:    n,
		sum:  make([]int, n<<1),
		pref: make([]int, n<<1),
	}
	s.Rebuild(vals)
	return s
}

func (s *Seg) pull(i int) {
	l := i << 1
	r := l | 1
	s.sum[i] = s.sum[l] + s.sum[r]
	p := s.pref[l]
	t := s.sum[l] + s.pref[r]
	if t > p {
		p = t
	}
	s.pref[i] = p
}

func (s *Seg) Set(pos, val int) {
	i := s.n + pos
	s.sum[i] = val
	if val > 0 {
		s.pref[i] = val
	} else {
		s.pref[i] = 0
	}
	for i >>= 1; i > 0; i >>= 1 {
		s.pull(i)
	}
}

func (s *Seg) Max() int {
	return s.pref[1]
}

func (s *Seg) Rebuild(vals []int) {
	for i := range s.sum {
		s.sum[i] = 0
		s.pref[i] = 0
	}
	for i, v := range vals {
		p := s.n + i
		s.sum[p] = v
		if v > 0 {
			s.pref[p] = v
		}
	}
	for i := s.n - 1; i > 0; i-- {
		s.pull(i)
	}
}

func sortByPos(ids []int, pos []int) {
	for i := 1; i < len(ids); i++ {
		v := ids[i]
		pv := pos[v]
		j := i - 1
		for j >= 0 && pos[ids[j]] > pv {
			ids[j+1] = ids[j]
			j--
		}
		ids[j+1] = v
	}
}

func sortByDer(ids []int, der []float64) {
	for i := 1; i < len(ids); i++ {
		v := ids[i]
		dv := der[v]
		j := i - 1
		for j >= 0 && der[ids[j]] > dv {
			ids[j+1] = ids[j]
			j--
		}
		ids[j+1] = v
	}
}

func appendRoots(events *[]Event, phi, q float64, a, b uint16) {
	if q < -1 {
		q = -1
	} else if q > 1 {
		q = 1
	}
	alpha := math.Acos(q)

	ang := phi - alpha
	if ang < 0 {
		ang += twoPi
	} else if ang >= twoPi {
		ang -= twoPi
	}
	if ang > epsBoundary && ang < math.Pi-epsBoundary {
		*events = append(*events, Event{ang: ang, a: a, b: b})
	}

	ang = phi + alpha
	if ang < 0 {
		ang += twoPi
	} else if ang >= twoPi {
		ang -= twoPi
	}
	if ang > epsBoundary && ang < math.Pi-epsBoundary {
		*events = append(*events, Event{ang: ang, a: a, b: b})
	}
}

func maxLine(x, y, r []float64) int {
	n := len(x)
	m := n << 1

	cconst := make([]float64, m)
	weight := make([]int, m)
	initIDs := make([]int, m)
	for i := 0; i < n; i++ {
		cconst[i<<1] = -r[i]
		cconst[i<<1|1] = r[i]
		weight[i<<1] = 1
		weight[i<<1|1] = -1
		initIDs[i<<1] = i << 1
		initIDs[i<<1|1] = i<<1 | 1
	}

	sort.Slice(initIDs, func(i, j int) bool {
		a := initIDs[i]
		b := initIDs[j]
		va := x[a>>1] + cconst[a]
		vb := x[b>>1] + cconst[b]
		if va != vb {
			return va < vb
		}
		da := y[a>>1]
		db := y[b>>1]
		if da != db {
			return da < db
		}
		return a < b
	})

	order := make([]int, m)
	pos := make([]int, m)
	seq := make([]int, m)
	for i, id := range initIDs {
		order[i] = id
		pos[id] = i
		seq[i] = weight[id]
	}

	seg := NewSeg(seq)
	best := seg.Max()

	events := make([]Event, 0, 4*n*(n-1))
	for i := 0; i < n; i++ {
		ri := r[i]
		a0 := uint16(i << 1)
		a1 := a0 | 1
		for j := i + 1; j < n; j++ {
			dx := x[i] - x[j]
			dy := y[i] - y[j]
			d := math.Hypot(dx, dy)
			phi := math.Atan2(dy, dx)
			rj := r[j]
			b0 := uint16(j << 1)
			b1 := b0 | 1

			appendRoots(&events, phi, (ri-rj)/d, a0, b0)
			appendRoots(&events, phi, (ri+rj)/d, a0, b1)
			appendRoots(&events, phi, -(ri+rj)/d, a1, b0)
			appendRoots(&events, phi, (rj-ri)/d, a1, b1)
		}
	}

	sort.Slice(events, func(i, j int) bool {
		return events[i].ang < events[j].ang
	})

	marks := make([]int, m)
	valAt := make([]float64, m)
	derAt := make([]float64, m)
	work := make([]int, 0, m)
	allIDs := make([]int, m)
	tmpSeq := make([]int, m)

	rebuild := func(ang float64) {
		ca := math.Cos(ang)
		sa := math.Sin(ang)
		for id := 0; id < m; id++ {
			c := id >> 1
			valAt[id] = x[c]*ca + y[c]*sa + cconst[id]
			derAt[id] = -x[c]*sa + y[c]*ca
			allIDs[id] = id
		}
		sort.Slice(allIDs, func(i, j int) bool {
			a := allIDs[i]
			b := allIDs[j]
			if valAt[a] != valAt[b] {
				return valAt[a] < valAt[b]
			}
			if derAt[a] != derAt[b] {
				return derAt[a] < derAt[b]
			}
			return a < b
		})
		l := 0
		for l < m {
			rg := l + 1
			base := valAt[allIDs[l]]
			for rg < m && math.Abs(valAt[allIDs[rg]]-base) <= epsValue {
				rg++
			}
			sortByDer(allIDs[l:rg], derAt)
			l = rg
		}
		for i, id := range allIDs {
			order[i] = id
			pos[id] = i
			tmpSeq[i] = weight[id]
		}
		seg.Rebuild(tmpSeq)
	}

	token := 0
	for i := 0; i < len(events); {
		ang := events[i].ang
		j := i + 1
		for j < len(events) && events[j].ang-ang <= epsAngle {
			j++
		}

		if j == i+1 {
			a := int(events[i].a)
			b := int(events[i].b)
			pa := pos[a]
			pb := pos[b]
			if pa > pb {
				pa, pb = pb, pa
				a, b = b, a
			}
			if pb != pa+1 {
				rebuild(ang)
			} else {
				order[pa], order[pb] = order[pb], order[pa]
				pos[a], pos[b] = pb, pa
				if weight[a] != weight[b] {
					seg.Set(pa, weight[b])
					seg.Set(pb, weight[a])
				}
			}
		} else {
			token++
			work = work[:0]
			for t := i; t < j; t++ {
				a := int(events[t].a)
				if marks[a] != token {
					marks[a] = token
					work = append(work, a)
				}
				b := int(events[t].b)
				if marks[b] != token {
					marks[b] = token
					work = append(work, b)
				}
			}

			sortByPos(work, pos)

			ca := math.Cos(ang)
			sa := math.Sin(ang)
			for _, id := range work {
				c := id >> 1
				valAt[id] = x[c]*ca + y[c]*sa + cconst[id]
				derAt[id] = -x[c]*sa + y[c]*ca
			}

			l := 0
			for l < len(work) {
				start := pos[work[l]]
				rg := l + 1
				base := valAt[work[l]]
				for rg < len(work) && math.Abs(valAt[work[rg]]-base) <= epsValue {
					rg++
				}
				sortByDer(work[l:rg], derAt)
				for t, id := range work[l:rg] {
					p := start + t
					old := order[p]
					order[p] = id
					pos[id] = p
					if weight[old] != weight[id] {
						seg.Set(p, weight[id])
					}
				}
				l = rg
			}
		}

		cur := seg.Max()
		if cur > best {
			best = cur
		}
		i = j
	}

	return best
}

func main() {
	in := bufio.NewReaderSize(os.Stdin, 1<<20)
	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	defer out.Flush()

	var n, k int
	fmt.Fscan(in, &n, &k)

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

	for i := 0; i < n; i++ {
		var xi, yi, ri int
		fmt.Fscan(in, &xi, &yi, &ri)
		x[i] = float64(xi)
		y[i] = float64(yi)
		r[i] = float64(ri)
	}

	t := maxLine(x, y, r)
	ans := int64(n) + int64(k)*int64(t) + int64(k)*(int64(k)-1)/2
	fmt.Fprintln(out, ans)
}