```go
package main
import (
"bufio"
"fmt"
"os"
"sort"
)
var (
reader *bufio.Reader
writer *bufio.Writer
)
func main() {
reader = bufio.NewReader(os.Stdin)
writer = bufio.NewWriter(os.Stdout)
defer writer.Flush()
var t int
fmt.Fscan(reader, &t)
for i := 0; i < t; i++ {
solve()
}
}
const LOGN = 19
func solve() {
var n int
fmt.Fscan(reader, &n)
a := make([]int, n)
b := make([]int, n)
pos := make([][]int, n+1)
for i := 0; i < n; i++ {
fmt.Fscan(reader, &a[i])
pos[a[i]] = append(pos[a[i]], i)
}
for i := 0; i < n; i++ {
fmt.Fscan(reader, &b[i])
}
for i := 0; i < n; i++ {
if a[i] > b[i] {
fmt.Fprintln(writer, "NO")
return
}
}
// Sparse Table for RMQ on a
// st[i][j] stores the max value in a[i...i+(1<<j)-1]
st := make([][LOGN]int, n)
logs := make([]int, n+1)
logs[1] = 0
for i := 2; i <= n; i++ {
logs[i] = logs[i/2] + 1
}
for i := 0; i < n; i++ {
st[i][0] = a[i]
}
for j := 1; j < LOGN; j++ {
len := 1 << (j - 1)
for i := 0; i+2*len <= n; i++ {
v1 := st[i][j-1]
v2 := st[i+len][j-1]
if v1 > v2 {
st[i][j] = v1
} else {
st[i][j] = v2
}
}
}
query := func(L, R int) int {
if L > R {
return 0
}
len := R - L + 1
k := logs[len]
v1 := st[L][k]
v2 := st[R-(1<<k)+1][k]
if v1 > v2 {
return v1
}
return v2
}
// prevSmaller[i]: nearest index to left such that b[index] < b[i]
prevSmaller := make([]int, n)
// nextSmaller[i]: nearest index to right such that b[index] < b[i]
nextSmaller := make([]int, n)
stack := make([]int, 0, n)
for i := 0; i < n; i++ {
for len(stack) > 0 && b[stack[len(stack)-1]] >= b[i] {
stack = stack[:len(stack)-1]
}
if len(stack) == 0 {
prevSmaller[i] = -1
} else {
prevSmaller[i] = stack[len(stack)-1]
}
stack = append(stack, i)
}
stack = stack[:0]
for i := n - 1; i >= 0; i-- {
for len(stack) > 0 && b[stack[len(stack)-1]] >= b[i] {
stack = stack[:len(stack)-1]
}
if len(stack) == 0 {
nextSmaller[i] = n
} else {
nextSmaller[i] = stack[len(stack)-1]
}
stack = append(stack, i)
}
for i := 0; i < n; i++ {
if a[i] < b[i] {
val := b[i]
found := false
idxList := pos[val]
if len(idxList) == 0 {
fmt.Fprintln(writer, "NO")
return
}
// Check Left Source
L := prevSmaller[i]
// The search range for source is limited by L (where b decreases)
// and any 'blocker' (where a > val)
// Find rightmost blocker in [L+1, i-1]
blockerIdx := -1
low, high := L+1, i-1
if low <= high && query(low, high) > val {
// There is a blocker, find the rightmost one
bsL, bsR := low, high
for bsL <= bsR {
mid := (bsL + bsR) >> 1
if query(mid, high) > val {
blockerIdx = mid
bsL = mid + 1
} else {
bsR = mid - 1
}
}
}
limitLeft := L
if blockerIdx != -1 {
limitLeft = blockerIdx
}
// We need a source in (limitLeft, i)
// i.e., index > limitLeft and index < i
k := sort.Search(len(idxList), func(j int) bool {
return idxList[j] > limitLeft
})
if k < len(idxList) && idxList[k] < i {
found = true
}
if !found {
// Check Right Source
R := nextSmaller[i]
// Find leftmost blocker in [i+1, R-1]
blockerIdx = -1
low, high = i+1, R-1
if low <= high && query(low, high) > val {
bsL, bsR := low, high
for bsL <= bsR {
mid := (bsL + bsR) >> 1
if query(low, mid) > val {
blockerIdx = mid
bsR = mid - 1
} else {
bsL = mid + 1
}
}
}
limitRight := R
if blockerIdx != -1 {
limitRight = blockerIdx
}
// We need a source in (i, limitRight)
k = sort.Search(len(idxList), func(j int) bool {
return idxList[j] > i
})
if k < len(idxList) && idxList[k] < limitRight {
found = true
}
}
if !found {
fmt.Fprintln(writer, "NO")
return
}
}
}
fmt.Fprintln(writer, "YES")
}
```