← Home
For problem statement at 1000-1999/1300-1399/1380-1389/1389/problemF.txt this is a correct solution, but verifier at 1000-1999/1300-1399/1380-1389/1389/verifierF.go ends with test 1 failed
input:
1
5
7 8 1
2 2 1
9 15 1
2 7 1
8 17 2
expected:4
got:1
exit status 1 can you fix the verifier? package main

import (
	"bufio"
	"io"
	"os"
	"sort"
	"strconv"
)

const negInf int64 = -1 << 60

type BIT struct {
	n   int
	bit []int64
}

func NewBIT(n int) *BIT {
	return &BIT{n: n, bit: make([]int64, n+2)}
}

func (b *BIT) Add(i int, v int64) {
	for i <= b.n {
		b.bit[i] += v
		i += i & -i
	}
}

func (b *BIT) Sum(i int) int64 {
	var res int64
	for i > 0 {
		res += b.bit[i]
		i -= i & -i
	}
	return res
}

type Seg struct {
	mx []int64
	lz []int64
}

func NewSeg(n int) *Seg {
	sz := 4*n + 5
	mx := make([]int64, sz)
	lz := make([]int64, sz)
	for i := range mx {
		mx[i] = negInf
	}
	return &Seg{mx: mx, lz: lz}
}

func (s *Seg) apply(p int, v int64) {
	s.mx[p] += v
	s.lz[p] += v
}

func (s *Seg) push(p int) {
	if s.lz[p] != 0 {
		v := s.lz[p]
		s.apply(p<<1, v)
		s.apply(p<<1|1, v)
		s.lz[p] = 0
	}
}

func (s *Seg) Add(p, l, r, ql, qr int, v int64) {
	if ql > r || qr < l {
		return
	}
	if ql <= l && r <= qr {
		s.apply(p, v)
		return
	}
	s.push(p)
	m := (l + r) >> 1
	if ql <= m {
		s.Add(p<<1, l, m, ql, qr, v)
	}
	if qr > m {
		s.Add(p<<1|1, m+1, r, ql, qr, v)
	}
	if s.mx[p<<1] > s.mx[p<<1|1] {
		s.mx[p] = s.mx[p<<1]
	} else {
		s.mx[p] = s.mx[p<<1|1]
	}
}

func (s *Seg) Set(p, l, r, idx int, v int64) {
	if l == r {
		s.mx[p] = v
		s.lz[p] = 0
		return
	}
	s.push(p)
	m := (l + r) >> 1
	if idx <= m {
		s.Set(p<<1, l, m, idx, v)
	} else {
		s.Set(p<<1|1, m+1, r, idx, v)
	}
	if s.mx[p<<1] > s.mx[p<<1|1] {
		s.mx[p] = s.mx[p<<1]
	} else {
		s.mx[p] = s.mx[p<<1|1]
	}
}

func (s *Seg) Query(p, l, r, ql, qr int) int64 {
	if ql > r || qr < l {
		return negInf
	}
	if ql <= l && r <= qr {
		return s.mx[p]
	}
	s.push(p)
	m := (l + r) >> 1
	left := s.Query(p<<1, l, m, ql, qr)
	right := s.Query(p<<1|1, m+1, r, ql, qr)
	if left > right {
		return left
	}
	return right
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	ptr := 0
	nextInt := func() int {
		for ptr < len(data) && (data[ptr] < '0' || data[ptr] > '9') {
			ptr++
		}
		v := 0
		for ptr < len(data) && data[ptr] >= '0' && data[ptr] <= '9' {
			v = v*10 + int(data[ptr]-'0')
			ptr++
		}
		return v
	}

	n := nextInt()
	L := make([]int, n)
	R := make([]int, n)
	C := make([]int, n)
	coords := make([]int, 0, 2*n)

	for i := 0; i < n; i++ {
		l := nextInt()
		r := nextInt()
		t := nextInt() - 1
		L[i], R[i], C[i] = l, r, t
		coords = append(coords, l, r)
	}

	sort.Ints(coords)
	vals := coords[:0]
	for _, x := range coords {
		if len(vals) == 0 || vals[len(vals)-1] != x {
			vals = append(vals, x)
		}
	}
	m := len(vals)

	start0 := make([]bool, m+1)
	start1 := make([]bool, m+1)
	heads0 := make([]int, m+1)
	heads1 := make([]int, m+1)
	for i := 0; i <= m; i++ {
		heads0[i] = -1
		heads1[i] = -1
	}

	leftIdx := make([]int, n)
	nextEnd := make([]int, n)

	for i := 0; i < n; i++ {
		li := sort.SearchInts(vals, L[i]) + 1
		ri := sort.SearchInts(vals, R[i]) + 1
		leftIdx[i] = li
		if C[i] == 0 {
			start0[li] = true
			nextEnd[i] = heads0[ri]
			heads0[ri] = i
		} else {
			start1[li] = true
			nextEnd[i] = heads1[ri]
			heads1[ri] = i
		}
	}

	seg0 := NewSeg(m)
	seg1 := NewSeg(m)
	bit0 := NewBIT(m)
	bit1 := NewBIT(m)

	var pref0, pref1 int64
	var total0, total1 int64
	var maxL0, maxL1 int

	for i := 1; i <= m; i++ {
		for e := heads0[i]; e != -1; e = nextEnd[e] {
			l := leftIdx[e]
			total0++
			if l > maxL0 {
				maxL0 = l
			}
			if l < m {
				seg0.Add(1, 1, m, l+1, m, -1)
				bit0.Add(l+1, -1)
			}
		}
		for e := heads1[i]; e != -1; e = nextEnd[e] {
			l := leftIdx[e]
			total1++
			if l > maxL1 {
				maxL1 = l
			}
			if l < m {
				seg1.Add(1, 1, m, l+1, m, -1)
				bit1.Add(l+1, -1)
			}
		}

		if start0[i] {
			seg0.Set(1, 1, m, i, pref1+bit0.Sum(i))
		}
		if start1[i] {
			seg1.Set(1, 1, m, i, pref0+bit1.Sum(i))
		}

		dp0 := negInf
		dp1 := negInf

		if total0 > 0 && maxL0 > 0 {
			best := seg0.Query(1, 1, m, 1, maxL0)
			if best > negInf/2 {
				dp0 = total0 + best
			}
		}
		if total1 > 0 && maxL1 > 0 {
			best := seg1.Query(1, 1, m, 1, maxL1)
			if best > negInf/2 {
				dp1 = total1 + best
			}
		}

		if dp0 > pref0 {
			pref0 = dp0
		}
		if dp1 > pref1 {
			pref1 = dp1
		}
	}

	ans := pref0
	if pref1 > ans {
		ans = pref1
	}

	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	out.WriteString(strconv.FormatInt(ans, 10))
	out.Flush()
}