← Home
For problem statement at 0-999/500-599/520-529/520/problemD.txt this is a correct solution, but verifier at 0-999/500-599/520-529/520/verifierD.go ends with All tests passed can you fix the verifier? package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"io"
	"os"
)

const MOD int64 = 1000000009

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) NextInt() int {
	for fs.idx < fs.n {
		c := fs.data[fs.idx]
		if c == '-' || (c >= '0' && c <= '9') {
			break
		}
		fs.idx++
	}
	sign := 1
	if fs.data[fs.idx] == '-' {
		sign = -1
		fs.idx++
	}
	val := 0
	for fs.idx < fs.n {
		c := fs.data[fs.idx]
		if c < '0' || c > '9' {
			break
		}
		val = val*10 + int(c-'0')
		fs.idx++
	}
	return sign * val
}

type Key struct {
	x int
	y int
}

type MinHeap []int

func (h MinHeap) Len() int            { return len(h) }
func (h MinHeap) Less(i, j int) bool  { return h[i] < h[j] }
func (h MinHeap) Swap(i, j int)       { h[i], h[j] = h[j], h[i] }
func (h *MinHeap) Push(x interface{}) { *h = append(*h, x.(int)) }
func (h *MinHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[:n-1]
	return x
}

type MaxHeap []int

func (h MaxHeap) Len() int            { return len(h) }
func (h MaxHeap) Less(i, j int) bool  { return h[i] > h[j] }
func (h MaxHeap) Swap(i, j int)       { h[i], h[j] = h[j], h[i] }
func (h *MaxHeap) Push(x interface{}) { *h = append(*h, x.(int)) }
func (h *MaxHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[:n-1]
	return x
}

func main() {
	fs := NewFastScanner()
	m := fs.NextInt()

	x := make([]int, m)
	y := make([]int, m)
	pos := make(map[Key]int, m*2)

	for i := 0; i < m; i++ {
		x[i] = fs.NextInt()
		y[i] = fs.NextInt()
		pos[Key{x[i], y[i]}] = i
	}

	present := make([]bool, m)
	for i := 0; i < m; i++ {
		present[i] = true
	}

	sup := make([]int, m)
	for i := 0; i < m; i++ {
		if y[i] == 0 {
			sup[i] = 0
			continue
		}
		c := 0
		yy := y[i] - 1
		if _, ok := pos[Key{x[i] - 1, yy}]; ok {
			c++
		}
		if _, ok := pos[Key{x[i], yy}]; ok {
			c++
		}
		if _, ok := pos[Key{x[i] + 1, yy}]; ok {
			c++
		}
		sup[i] = c
	}

	findSole := func(i int) int {
		yy := y[i] - 1
		if yy < 0 {
			return -1
		}
		if j, ok := pos[Key{x[i] - 1, yy}]; ok && present[j] {
			return j
		}
		if j, ok := pos[Key{x[i], yy}]; ok && present[j] {
			return j
		}
		if j, ok := pos[Key{x[i] + 1, yy}]; ok && present[j] {
			return j
		}
		return -1
	}

	bad := make([]int, m)
	for i := 0; i < m; i++ {
		if sup[i] == 1 {
			t := findSole(i)
			bad[t]++
		}
	}

	removable := make([]bool, m)
	minH := &MinHeap{}
	maxH := &MaxHeap{}
	heap.Init(minH)
	heap.Init(maxH)

	updateStatus := func(i int) {
		if !present[i] {
			removable[i] = false
			return
		}
		if bad[i] == 0 {
			if !removable[i] {
				removable[i] = true
				heap.Push(minH, i)
				heap.Push(maxH, i)
			}
		} else {
			removable[i] = false
		}
	}

	for i := 0; i < m; i++ {
		if bad[i] == 0 {
			removable[i] = true
			heap.Push(minH, i)
			heap.Push(maxH, i)
		}
	}

	ans := int64(0)
	base := int64(m)

	for step := 0; step < m; step++ {
		var u int
		if step%2 == 0 {
			for {
				u = heap.Pop(maxH).(int)
				if present[u] && removable[u] && bad[u] == 0 {
					break
				}
			}
		} else {
			for {
				u = heap.Pop(minH).(int)
				if present[u] && removable[u] && bad[u] == 0 {
					break
				}
			}
		}

		ans = (ans*base + int64(u)) % MOD

		oldSup := sup[u]
		present[u] = false
		removable[u] = false

		affected := make([]int, 0, 4)

		if oldSup == 1 {
			t := findSole(u)
			bad[t]--
			affected = append(affected, t)
		}

		yy := y[u] + 1
		if v, ok := pos[Key{x[u] - 1, yy}]; ok && present[v] {
			sup[v]--
			if sup[v] == 1 {
				t := findSole(v)
				bad[t]++
				affected = append(affected, t)
			}
		}
		if v, ok := pos[Key{x[u], yy}]; ok && present[v] {
			sup[v]--
			if sup[v] == 1 {
				t := findSole(v)
				bad[t]++
				affected = append(affected, t)
			}
		}
		if v, ok := pos[Key{x[u] + 1, yy}]; ok && present[v] {
			sup[v]--
			if sup[v] == 1 {
				t := findSole(v)
				bad[t]++
				affected = append(affected, t)
			}
		}

		for _, t := range affected {
			updateStatus(t)
		}
	}

	out := bufio.NewWriter(os.Stdout)
	fmt.Fprint(out, ans)
	out.Flush()
}