← Home
```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

// IO helpers
var reader *bufio.Reader
var writer *bufio.Writer

func init() {
	reader = bufio.NewReader(os.Stdin)
	writer = bufio.NewWriter(os.Stdout)
}

func readInt() int {
	var x int
	for {
		b, err := reader.ReadByte()
		if err != nil {
			return x
		}
		if b >= '0' && b <= '9' {
			x = int(b - '0')
			break
		}
	}
	for {
		b, err := reader.ReadByte()
		if err != nil {
			break
		}
		if b < '0' || b > '9' {
			break
		}
		x = x*10 + int(b-'0')
	}
	return x
}

func printInt(x int) {
	fmt.Fprint(writer, x, " ")
}

// Segment Tree for Max Weight (Lazy Propagation)
type MaxWTree struct {
	n    int
	max  []int
	lazy []int
}

func NewMaxWTree(n int) *MaxWTree {
	size := 1
	for size <= n {
		size *= 2
	}
	tree := &MaxWTree{
		n:    size,
		max:  make([]int, 2*size),
		lazy: make([]int, 2*size),
	}
	// Initialize with a sufficiently small number
	for i := 0; i < 2*size; i++ {
		tree.max[i] = -1e18
	}
	return tree
}

func (t *MaxWTree) push(x int) {
	if t.lazy[x] != 0 {
		if 2*x < len(t.lazy) {
			t.lazy[2*x] += t.lazy[x]
			t.max[2*x] += t.lazy[x]
			t.lazy[2*x+1] += t.lazy[x]
			t.max[2*x+1] += t.lazy[x]
		}
		t.lazy[x] = 0
	}
}

func (t *MaxWTree) updatePoint(x, l, r, idx, val int) {
	if l == r {
		t.max[x] = val
		t.lazy[x] = 0
		return
	}
	t.push(x)
	mid := (l + r) / 2
	if idx <= mid {
		t.updatePoint(2*x, l, mid, idx, val)
	} else {
		t.updatePoint(2*x+1, mid+1, r, idx, val)
	}
	t.max[x] = max(t.max[2*x], t.max[2*x+1])
}

func (t *MaxWTree) addRange(x, l, r, ql, qr, val int) {
	if l > qr || r < ql {
		return
	}
	if l >= ql && r <= qr {
		t.max[x] += val
		t.lazy[x] += val
		return
	}
	t.push(x)
	mid := (l + r) / 2
	t.addRange(2*x, l, mid, ql, qr, val)
	t.addRange(2*x+1, mid+1, r, ql, qr, val)
	t.max[x] = max(t.max[2*x], t.max[2*x+1])
}

func (t *MaxWTree) UpdatePoint(idx, val int) {
	t.updatePoint(1, 0, t.n-1, idx, val)
}

func (t *MaxWTree) AddRange(ql, qr, val int) {
	t.addRange(1, 0, t.n-1, ql, qr, val)
}

func (t *MaxWTree) QueryAll() int {
	return t.max[1]
}

// Segment Tree for P values (Min Query + Search)
type PTree struct {
	n   int
	min []int
}

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

func (t *PTree) update(x, l, r, idx, val int) {
	if l == r {
		t.min[x] = val
		return
	}
	mid := (l + r) / 2
	if idx <= mid {
		t.update(2*x, l, mid, idx, val)
	} else {
		t.update(2*x+1, mid+1, r, idx, val)
	}
	t.min[x] = min(t.min[2*x], t.min[2*x+1])
}

func (t *PTree) Update(idx, val int) {
	t.update(1, 0, t.n-1, idx, val)
}

func (t *PTree) findFirst(x, l, r, ql, qr, thresh int) int {
	if l > qr || r < ql || t.min[x] >= thresh {
		return -1
	}
	if l == r {
		return l
	}
	mid := (l + r) / 2
	res := t.findFirst(2*x, l, mid, ql, qr, thresh)
	if res != -1 {
		return res
	}
	return t.findFirst(2*x+1, mid+1, r, ql, qr, thresh)
}

func (t *PTree) FindFirst(ql, qr, thresh int) int {
	return t.findFirst(1, 0, t.n-1, ql, qr, thresh)
}

// Set Tree to manage ValidSet (Pred/Succ)
type SetTree struct {
	n   int
	max []int
	min []int
}

func NewSetTree(n int) *SetTree {
	size := 1
	for size <= n {
		size *= 2
	}
	tree := &SetTree{
		n:   size,
		max: make([]int, 2*size),
		min: make([]int, 2*size),
	}
	for i := 0; i < 2*size; i++ {
		tree.max[i] = -1
		tree.min[i] = int(1e9)
	}
	return tree
}

func (t *SetTree) update(x, l, r, idx int, present bool) {
	if l == r {
		if present {
			t.max[x] = l
			t.min[x] = l
		} else {
			t.max[x] = -1
			t.min[x] = int(1e9)
		}
		return
	}
	mid := (l + r) / 2
	if idx <= mid {
		t.update(2*x, l, mid, idx, present)
	} else {
		t.update(2*x+1, mid+1, r, idx, present)
	}
	t.max[x] = max(t.max[2*x], t.max[2*x+1])
	t.min[x] = min(t.min[2*x], t.min[2*x+1])
}

func (t *SetTree) Insert(idx int) {
	t.update(1, 0, t.n-1, idx, true)
}

func (t *SetTree) Remove(idx int) {
	t.update(1, 0, t.n-1, idx, false)
}

func (t *SetTree) findPrev(x, l, r, ql, qr int) int {
	if l > qr || r < ql || t.max[x] == -1 {
		return -1
	}
	if l == r {
		return l
	}
	mid := (l + r) / 2
	res := t.findPrev(2*x+1, mid+1, r, ql, qr)
	if res != -1 {
		return res
	}
	return t.findPrev(2*x, l, mid, ql, qr)
}

func (t *SetTree) FindPrev(idx int) int {
	if idx == 0 {
		return -1
	}
	return t.findPrev(1, 0, t.n-1, 0, idx-1)
}

func (t *SetTree) findNext(x, l, r, ql, qr int) int {
	if l > qr || r < ql || t.min[x] == int(1e9) {
		return -1
	}
	if l == r {
		return l
	}
	mid := (l + r) / 2
	res := t.findNext(2*x, l, mid, ql, qr)
	if res != -1 {
		return res
	}
	return t.findNext(2*x+1, mid+1, r, ql, qr)
}

func (t *SetTree) FindNext(idx int) int {
	return t.findNext(1, 0, t.n-1, idx+1, t.n-1)
}

// Fenwick Tree for C values
type Fenwick struct {
	n    int
	tree []int
}

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

func (f *Fenwick) Add(idx, val int) {
	for idx <= f.n {
		f.tree[idx] += val
		idx += idx & -idx
	}
}

func (f *Fenwick) Query(idx int) int {
	sum := 0
	for idx > 0 {
		sum += f.tree[idx]
		idx -= idx & -idx
	}
	return sum
}

func (f *Fenwick) RangeAdd(l, r, val int) {
	f.Add(l, val)
	f.Add(r+1, -val)
}

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

func solve() {
	n := readInt()
	a := make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = readInt()
	}

	size := n + 2
	maxW := NewMaxWTree(size)
	pTree := NewPTree(size)
	setTree := NewSetTree(size)
	cTree := NewFenwick(size + 5)

	pVal := make([]int, size)
	vVal := make([]int, size)
	inSet := make([]bool, size)

	inSet[0] = true
	setTree.Insert(0)
	maxW.UpdatePoint(0, 0)

	for r := 1; r <= n; r++ {
		x := a[r-1]

		maxW.AddRange(0, x, 1)
		cTree.RangeAdd(x+2, size+1, 1)

		if inSet[x] {
			u := setTree.FindPrev(x)
			y := setTree.FindNext(x)

			inSet[x] = false
			setTree.Remove(x)
			maxW.UpdatePoint(x, -1e18)

			pVal[x] = r
			pTree.Update(x, r)
			c_x := cTree.Query(x + 1)
			vVal[x] = r - c_x

			if y == -1 {
				y = size
			}
			thresh := int(1e9)
			if u != -1 {
				thresh = pVal[u]
			}

			start := u + 1
			limit := y - 1
			
			curr := start
			for curr <= limit {
				idx := pTree.FindFirst(curr, limit, thresh)
				if idx == -1 {
					break
				}
				
				inSet[idx] = true
				setTree.Insert(idx)
				
				c_idx := cTree.Query(idx + 1)
				score := r - c_idx
				val := score - vVal[idx]
				maxW.UpdatePoint(idx, val)

				thresh = pVal[idx]
				curr = idx + 1
			}
		} else {
			pVal[x] = r
			pTree.Update(x, r)
			c_x := cTree.Query(x + 1)
			vVal[x] = r - c_x
		}
		
		ans := maxW.QueryAll()
		if ans < 0 {
			ans = 0
		}
		printInt(ans)
	}
	fmt.Fprintln(writer)
}

func main() {
	defer writer.Flush()
	t := readInt()
	for i := 0; i < t; i++ {
		solve()
	}
}
```