← Home
For problem statement at 1000-1999/1600-1699/1600-1609/1601/problemD.txt this is a correct solution, but verifier at 1000-1999/1600-1699/1600-1609/1601/verifierD.go ends with All 100 tests passed can you fix the verifier? package main

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

const negInf int64 = -1 << 60

type Fenwick struct {
	t []int64
}

func NewFenwick(n int) *Fenwick {
	return &Fenwick{t: make([]int64, n+1)}
}

func (f *Fenwick) Add(i int, v int64) {
	for i++; i < len(f.t); i += i & -i {
		f.t[i] += v
	}
}

func (f *Fenwick) Sum(i int) int64 {
	var res int64
	for i++; i > 0; i -= i & -i {
		res += f.t[i]
	}
	return res
}

type SegTree struct {
	n  int
	mx []int64
	lz []int64
}

func NewSegTree(n int) *SegTree {
	s := &SegTree{
		n:  n,
		mx: make([]int64, 4*n+5),
		lz: make([]int64, 4*n+5),
	}
	for i := range s.mx {
		s.mx[i] = negInf
	}
	return s
}

func max64(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

func (s *SegTree) push(v int) {
	if s.lz[v] != 0 {
		add := s.lz[v]
		lc, rc := v<<1, v<<1|1
		s.mx[lc] += add
		s.lz[lc] += add
		s.mx[rc] += add
		s.lz[rc] += add
		s.lz[v] = 0
	}
}

func (s *SegTree) RangeAdd(l, r int, val int64) {
	if l > r {
		return
	}
	s.rangeAdd(1, 0, s.n-1, l, r, val)
}

func (s *SegTree) rangeAdd(v, tl, tr, l, r int, val int64) {
	if l <= tl && tr <= r {
		s.mx[v] += val
		s.lz[v] += val
		return
	}
	s.push(v)
	tm := (tl + tr) >> 1
	if l <= tm {
		s.rangeAdd(v<<1, tl, tm, l, r, val)
	}
	if r > tm {
		s.rangeAdd(v<<1|1, tm+1, tr, l, r, val)
	}
	s.mx[v] = max64(s.mx[v<<1], s.mx[v<<1|1])
}

func (s *SegTree) Query(l, r int) int64 {
	if l > r {
		return negInf
	}
	return s.query(1, 0, s.n-1, l, r)
}

func (s *SegTree) query(v, tl, tr, l, r int) int64 {
	if l <= tl && tr <= r {
		return s.mx[v]
	}
	s.push(v)
	tm := (tl + tr) >> 1
	res := negInf
	if l <= tm {
		res = max64(res, s.query(v<<1, tl, tm, l, r))
	}
	if r > tm {
		res = max64(res, s.query(v<<1|1, tm+1, tr, l, r))
	}
	return res
}

func (s *SegTree) PointSet(pos int, val int64) {
	s.pointSet(1, 0, s.n-1, pos, val)
}

func (s *SegTree) pointSet(v, tl, tr, pos int, val int64) {
	if tl == tr {
		s.mx[v] = val
		s.lz[v] = 0
		return
	}
	s.push(v)
	tm := (tl + tr) >> 1
	if pos <= tm {
		s.pointSet(v<<1, tl, tm, pos, val)
	} else {
		s.pointSet(v<<1|1, tm+1, tr, pos, val)
	}
	s.mx[v] = max64(s.mx[v<<1], s.mx[v<<1|1])
}

func upperBound(a []int, x int) int {
	l, r := 0, len(a)
	for l < r {
		m := (l + r) >> 1
		if a[m] <= x {
			l = m + 1
		} else {
			r = m
		}
	}
	return l
}

type Item struct {
	s    int
	idxA int
}

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

	n := nextInt()
	d := nextInt()

	sArr := make([]int, n)
	aArr := make([]int, n)
	vals := make([]int, 0, n+1)
	vals = append(vals, d)

	for i := 0; i < n; i++ {
		s := nextInt()
		a := nextInt()
		sArr[i] = s
		aArr[i] = a
		if a > d {
			vals = append(vals, a)
		}
	}

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

	m := len(levels)
	idxMap := make(map[int]int, m)
	for i, v := range levels {
		idxMap[v] = i
	}

	maxS := make([]int, m)
	maxLow := make([]int, m)
	for i := 0; i < m; i++ {
		maxS[i] = -1
		maxLow[i] = -1
	}

	active := make([]Item, 0, n)
	bit := NewFenwick(m)

	for i := 0; i < n; i++ {
		s := sArr[i]
		a := aArr[i]

		idxA := 0
		if a > d {
			idxA = idxMap[a]
			if s > maxS[idxA] {
				maxS[idxA] = s
			}
			if s < a && s > maxLow[idxA] {
				maxLow[idxA] = s
			}
		}

		if s >= d {
			active = append(active, Item{s: s, idxA: idxA})
			bit.Add(idxA, 1)
		}
	}

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

	seg := NewSegTree(m)
	seg.PointSet(0, 0)

	ans := bit.Sum(0)
	ptr := 0

	for qIdx := 1; qIdx < m; qIdx++ {
		q := levels[qIdx]

		for ptr < len(active) && active[ptr].s < q {
			bit.Add(active[ptr].idxA, -1)
			seg.RangeAdd(active[ptr].idxA, m-1, 1)
			ptr++
		}

		cover := bit.Sum(qIdx)
		best := negInf

		if maxS[qIdx] >= d {
			lim := upperBound(levels, maxS[qIdx]) - 1
			if lim > qIdx-1 {
				lim = qIdx - 1
			}
			if lim >= 0 {
				v := seg.Query(0, lim)
				if v > best {
					best = v
				}
			}
		}

		if maxLow[qIdx] >= d {
			lim := upperBound(levels, maxLow[qIdx]) - 1
			if lim > qIdx-1 {
				lim = qIdx - 1
			}
			if lim >= 0 {
				v := seg.Query(0, lim) + 1
				if v > best {
					best = v
				}
			}
		}

		if best != negInf {
			dp := cover + best
			if dp > ans {
				ans = dp
			}
			seg.PointSet(qIdx, dp-cover)
		} else {
			seg.PointSet(qIdx, negInf)
		}
	}

	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	fmt.Fprint(out, ans)
	out.Flush()
}