← Home
```go
package main

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

type Rook struct {
	x, y int
}

type Query struct {
	id             int
	x1, y1, x2, y2 int
}

type SegTree struct {
	tree []int
	n    int
}

func NewSegTree(size int) *SegTree {
	n := 1
	for n < size {
		n *= 2
	}
	return &SegTree{
		tree: make([]int, 2*n),
		n:    n,
	}
}

func (st *SegTree) update(p int, val int) {
	p += st.n
	st.tree[p] = val
	for p > 1 {
		p >>= 1
		st.tree[p] = st.tree[p<<1]
		if st.tree[(p<<1)|1] < st.tree[p] {
			st.tree[p] = st.tree[(p<<1)|1]
		}
	}
}

func (st *SegTree) query(l, r int) int {
	res := 1000000000
	l += st.n
	r += st.n + 1
	for l < r {
		if l&1 != 0 {
			if st.tree[l] < res {
				res = st.tree[l]
			}
			l++
		}
		if r&1 != 0 {
			r--
			if st.tree[r] < res {
				res = st.tree[r]
			}
		}
		l >>= 1
		r >>= 1
	}
	return res
}

func main() {
	buffer, _ := io.ReadAll(os.Stdin)
	pos := 0
	nextInt := func() int {
		for pos < len(buffer) && buffer[pos] <= ' ' {
			pos++
		}
		if pos >= len(buffer) {
			return 0
		}
		res := 0
		for pos < len(buffer) && buffer[pos] > ' ' {
			res = res*10 + int(buffer[pos]-'0')
			pos++
		}
		return res
	}

	n := nextInt()
	m := nextInt()
	k := nextInt()
	q := nextInt()

	if n == 0 {
		return
	}

	rooks := make([]Rook, k)
	for i := 0; i < k; i++ {
		rooks[i].x = nextInt()
		rooks[i].y = nextInt()
	}

	queries := make([]Query, q)
	for i := 0; i < q; i++ {
		queries[i].id = i
		queries[i].x1 = nextInt()
		queries[i].y1 = nextInt()
		queries[i].x2 = nextInt()
		queries[i].y2 = nextInt()
	}

	ans := make([]bool, q)

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

	rowQueries := make([]Query, q)
	copy(rowQueries, queries)
	sort.Slice(rowQueries, func(i, j int) bool {
		return rowQueries[i].y2 < rowQueries[j].y2
	})

	stRow := NewSegTree(n + 2)
	rookIdx := 0
	for _, qry := range rowQueries {
		for rookIdx < k && rooks[rookIdx].y <= qry.y2 {
			stRow.update(rooks[rookIdx].x, rooks[rookIdx].y)
			rookIdx++
		}
		if stRow.query(qry.x1, qry.x2) >= qry.y1 {
			ans[qry.id] = true
		}
	}

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

	colQueries := make([]Query, q)
	copy(colQueries, queries)
	sort.Slice(colQueries, func(i, j int) bool {
		return colQueries[i].x2 < colQueries[j].x2
	})

	stCol := NewSegTree(m + 2)
	rookIdx = 0
	for _, qry := range colQueries {
		for rookIdx < k && rooks[rookIdx].x <= qry.x2 {
			stCol.update(rooks[rookIdx].y, rooks[rookIdx].x)
			rookIdx++
		}
		if stCol.query(qry.y1, qry.y2) >= qry.x1 {
			ans[qry.id] = true
		}
	}

	writer := bufio.NewWriter(os.Stdout)
	for i := 0; i < q; i++ {
		if ans[i] {
			fmt.Fprintln(writer, "YES")
		} else {
			fmt.Fprintln(writer, "NO")
		}
	}
	writer.Flush()
}
```