```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()
}
}
```