For problem statement at 0-999/200-299/270-279/274/problemE.txt this is a correct solution, but verifier at 0-999/200-299/270-279/274/verifierE.go ends with case 1 failed: expected "15" got "17"
input:
8 10 4
7 6
6 8
1 6
4 6
8 2 NE
exit status 1 can you fix the verifier? ```go
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
)
type Point struct {
x, y int
}
type State struct {
x, y, dx, dy int
}
type Segment struct {
x1, y1, x2, y2, dx, dy int
}
type Interval struct {
min, max int
}
type Event struct {
U int
typ int // 1 for Add, 2 for Query, 3 for Remove
V1 int
V2 int
}
var bit []int
func add(idx, val int) {
for ; idx < len(bit); idx += idx & -idx {
bit[idx] += val
}
}
func query(idx int) int {
sum := 0
for ; idx > 0; idx -= idx & -idx {
sum += bit[idx]
}
return sum
}
func merge(intervals []Interval) []Interval {
if len(intervals) == 0 {
return nil
}
sort.Slice(intervals, func(i, j int) bool {
return intervals[i].min < intervals[j].min
})
var merged []Interval
curr := intervals[0]
for i := 1; i < len(intervals); i++ {
if intervals[i].min <= curr.max {
if intervals[i].max > curr.max {
curr.max = intervals[i].max
}
} else {
merged = append(merged, curr)
curr = intervals[i]
}
}
merged = append(merged, curr)
return merged
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
const maxCapacity = 2 * 1024 * 1024
buf := make([]byte, maxCapacity)
scanner.Buffer(buf, maxCapacity)
scanner.Split(bufio.ScanWords)
scanInt := func() int {
scanner.Scan()
n, _ := strconv.Atoi(scanner.Text())
return n
}
scanString := func() string {
scanner.Scan()
return scanner.Text()
}
if !scanner.Scan() {
return
}
n, _ := strconv.Atoi(scanner.Text())
m := scanInt()
k := scanInt()
blockedSet := make(map[Point]bool)
blocks0 := make(map[int][]int)
blocks1 := make(map[int][]int)
for i := 0; i < k; i++ {
bx := scanInt()
by := scanInt()
blockedSet[Point{bx, by}] = true
blocks0[bx-by] = append(blocks0[bx-by], bx)
blocks1[bx+by] = append(blocks1[bx+by], bx)
}
for _, arr := range blocks0 {
sort.Ints(arr)
}
for _, arr := range blocks1 {
sort.Ints(arr)
}
xs := scanInt()
ys := scanInt()
dirStr := scanString()
dx, dy := 0, 0
switch dirStr {
case "NE":
dx, dy = -1, 1
case "NW":
dx, dy = -1, -1
case "SE":
dx, dy = 1, 1
case "SW":
dx, dy = 1, -1
}
isBlocked := func(cx, cy int) bool {
if cx < 1 || cx > n || cy < 1 || cy > m {
return true
}
return blockedSet[Point{cx, cy}]
}
getMinT := func(x, y, dx, dy int) int {
dir := dx * dy
var blocks map[int][]int
if dir == 1 {
blocks = blocks0
} else {
blocks = blocks1
}
C := x - dir*y
tMin := n + m + 5
tbx := x
if dx == 1 {
tbx = n + 1 - x
}
tby := y
if dy == 1 {
tby = m + 1 - y
}
if tbx < tMin {
tMin = tbx
}
if tby < tMin {
tMin = tby
}
lines := []int{C, C + dx, C - dx}
for i, L := range lines {
arr, ok := blocks[L]
if !ok {
continue
}
if dx == 1 {
idx := sort.Search(len(arr), func(j int) bool {
if i == 2 {
return arr[j] >= x
}
return arr[j] > x
})
if idx < len(arr) {
u := arr[idx]
t := u - x
if i == 2 {
t++
}
if t < tMin {
tMin = t
}
}
} else {
idx := sort.Search(len(arr), func(j int) bool {
if i == 2 {
return arr[j] > x
}
return arr[j] >= x
})
idx--
if idx >= 0 {
u := arr[idx]
t := x - u
if i == 2 {
t++
}
if t < tMin {
tMin = t
}
}
}
}
return tMin
}
visitedStates := make(map[State]bool)
var segments []Segment
x, y := xs, ys
for {
state := State{x, y, dx, dy}
if visitedStates[state] {
break
}
visitedStates[state] = true
t := getMinT(x, y, dx, dy)
nx := x + (t-1)*dx
ny := y + (t-1)*dy
segments = append(segments, Segment{x, y, nx, ny, dx, dy})
bx := isBlocked(nx+dx, ny)
by := isBlocked(nx, ny+dy)
bxy := isBlocked(nx+dx, ny+dy)
var ndx, ndy int
if bx && by {
ndx, ndy = -dx, -dy
} else if bx {
ndx, ndy = -dx, dy
} else if by {
ndx, ndy = dx, -dy
} else if bxy {
ndx, ndy = -dx, -dy
} else {
ndx, ndy = dx, dy
}
x, y, dx, dy = nx, ny, ndx, ndy
}
horizMap := make(map[int][]Interval)
vertMap := make(map[int][]Interval)
for _, seg := range segments {
U1 := seg.x1 + seg.y1
U2 := seg.x2 + seg.y2
V1 := seg.x1 - seg.y1
V2 := seg.x2 - seg.y2
if seg.dx*seg.dy == 1 {
if U1 > U2 {
U1, U2 = U2, U1
}
horizMap[V1] = append(horizMap[V1], Interval{U1, U2})
} else {
if V1 > V2 {
V1, V2 = V2, V1
}
vertMap[U1] = append(vertMap[U1], Interval{V1, V2})
}
}
var totalCells int64 = 0
mergedHoriz := make(map[int][]Interval)
for V, intervals := range horizMap {
m := merge(intervals)
mergedHoriz[V] = m
for _, iv := range m {
totalCells += int64((iv.max-iv.min)/2 + 1)
}
}
mergedVert := make(map[int][]Interval)
for U, intervals := range vertMap {
m := merge(intervals)
mergedVert[U] = m
for _, iv := range m {
totalCells += int64((iv.max-iv.min)/2 + 1)
}
}
var events []Event
for V, intervals := range mergedHoriz {
for _, iv := range intervals {
events = append(events, Event{U: iv.min, typ: 1, V1: V + 100005})
events = append(events, Event{U: iv.max, typ: 3, V1: V + 100005})
}
}
for U, intervals := range mergedVert {
for _, iv := range intervals {
events = append(events, Event{U: U, typ: 2, V1: iv.min + 100005, V2: iv.max + 100005})
}
}
sort.Slice(events, func(i, j int) bool {
if events[i].U != events[j].U {
return events[i].U < events[j].U
}
return events[i].typ < events[j].typ
})
bit = make([]int, 300005)
var intersections int64 = 0
for _, ev := range events {
if ev.typ == 1 {
add(ev.V1, 1)
} else if ev.typ == 3 {
add(ev.V1, -1)
} else if ev.typ == 2 {
intersections += int64(query(ev.V2) - query(ev.V1-1))
}
}
fmt.Println(totalCells - intersections)
}
```