← Home
```go
package main

import (
	"bufio"
	"os"
)

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

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func scanInt(reader *bufio.Reader) int {
	var res int
	var c byte
	var err error
	for {
		c, err = reader.ReadByte()
		if err != nil {
			return 0
		}
		if c >= '0' && c <= '9' {
			break
		}
	}
	res = int(c - '0')
	for {
		c, err = reader.ReadByte()
		if err != nil {
			break
		}
		if c >= '0' && c <= '9' {
			res = res*10 + int(c-'0')
		} else {
			break
		}
	}
	return res
}

func main() {
	reader := bufio.NewReaderSize(os.Stdin, 65536)
	n := scanInt(reader)
	m := scanInt(reader)
	k := scanInt(reader)
	q := scanInt(reader)

	rooksByY := make([][]int, m+1)
	rooksByX := make([][]int, n+1)

	for i := 0; i < k; i++ {
		x := scanInt(reader)
		y := scanInt(reader)
		rooksByY[y] = append(rooksByY[y], x)
		rooksByX[x] = append(rooksByX[x], y)
	}

	queriesByY2 := make([][]Query, m+1)
	queriesByX2 := make([][]Query, n+1)

	for i := 0; i < q; i++ {
		x1 := scanInt(reader)
		y1 := scanInt(reader)
		x2 := scanInt(reader)
		y2 := scanInt(reader)
		query := Query{id: i, x1: x1, y1: y1, x2: x2, y2: y2}
		queriesByY2[y2] = append(queriesByY2[y2], query)
		queriesByX2[x2] = append(queriesByX2[x2], query)
	}

	maxDim := n
	if m > maxDim {
		maxDim = m
	}

	N := 1
	for N <= maxDim {
		N *= 2
	}

	tree := make([]int, 2*N)

	update := func(idx, val int) {
		idx += N
		tree[idx] = val
		for idx > 1 {
			idx /= 2
			tree[idx] = min(tree[2*idx], tree[2*idx+1])
		}
	}

	queryRange := func(l, r int) int {
		l += N
		r += N
		res := 1000000000
		for l <= r {
			if l%2 == 1 {
				res = min(res, tree[l])
				l++
			}
			if r%2 == 0 {
				res = min(res, tree[r])
				r--
			}
			l /= 2
			r /= 2
		}
		return res
	}

	ans := make([]bool, q)

	for y := 1; y <= m; y++ {
		for _, x := range rooksByY[y] {
			update(x-1, y)
		}
		for _, qry := range queriesByY2[y] {
			if queryRange(qry.x1-1, qry.x2-1) >= qry.y1 {
				ans[qry.id] = true
			}
		}
	}

	for i := 0; i < 2*N; i++ {
		tree[i] = 0
	}

	for x := 1; x <= n; x++ {
		for _, y := range rooksByX[x] {
			update(y-1, x)
		}
		for _, qry := range queriesByX2[x] {
			if queryRange(qry.y1-1, qry.y2-1) >= qry.x1 {
				ans[qry.id] = true
			}
		}
	}

	writer := bufio.NewWriterSize(os.Stdout, 65536)
	for i := 0; i < q; i++ {
		if ans[i] {
			writer.WriteString("YES\n")
		} else {
			writer.WriteString("NO\n")
		}
	}
	writer.Flush()
}
```