← Home
```go
package main

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

var scanner *bufio.Scanner
var writer *bufio.Writer

func init() {
	scanner = bufio.NewScanner(os.Stdin)
	scanner.Buffer(make([]byte, 2048*1024), 20*1024*1024)
	scanner.Split(bufio.ScanWords)
	writer = bufio.NewWriter(os.Stdout)
}

func scanInt() int {
	scanner.Scan()
	x := 0
	s := scanner.Bytes()
	for _, b := range s {
		x = x*10 + int(b-'0')
	}
	return x
}

type Mushroom struct {
	v, id int
}

type Pair struct {
	val, k int
}

func greater(p1, p2 Pair) bool {
	if p1.val != p2.val {
		return p1.val > p2.val
	}
	return p1.k < p2.k
}

func maxPair(p1, p2 Pair) Pair {
	if greater(p1, p2) {
		return p1
	}
	return p2
}

type Node struct {
	max_val_set1 int
	min_diff     int
	best_set1    Pair
	best_set2    Pair
	lazy         int
}

var tree []Node
var L []int
var n int

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

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

func build(node, l, r int) {
	tree[node].lazy = 0
	tree[node].best_set2 = Pair{-1, -1}
	if l == r {
		tree[node].max_val_set1 = 0
		tree[node].min_diff = L[l]
		tree[node].best_set1 = Pair{0, l}
		return
	}
	mid := (l + r) / 2
	build(node*2, l, mid)
	build(node*2+1, mid+1, r)
	merge(node)
}

func merge(node int) {
	left := node * 2
	right := node * 2 + 1
	tree[node].max_val_set1 = max(tree[left].max_val_set1, tree[right].max_val_set1)
	tree[node].min_diff = min(tree[left].min_diff, tree[right].min_diff)
	tree[node].best_set1 = maxPair(tree[left].best_set1, tree[right].best_set1)
	tree[node].best_set2 = maxPair(tree[left].best_set2, tree[right].best_set2)
}

func push(node int) {
	if tree[node].lazy != 0 {
		lz := tree[node].lazy
		left := node * 2
		right := node * 2 + 1
		apply(left, lz)
		apply(right, lz)
		tree[node].lazy = 0
	}
}

func apply(node, val int) {
	tree[node].lazy += val
	if tree[node].max_val_set1 != -1 {
		tree[node].max_val_set1 += val
		tree[node].min_diff -= val
		tree[node].best_set1.val += val
	}
}

func update(node, l, r, ql, qr int) {
	if ql > r || qr < l {
		return
	}
	if ql <= l && r <= qr {
		if tree[node].max_val_set1 == -1 {
			apply(node, 1)
			return
		}
		if tree[node].min_diff > 1 {
			apply(node, 1)
			return
		}
	}
	if l == r {
		apply(node, 1)
		if tree[node].min_diff <= 0 {
			tree[node].max_val_set1 = -1
			tree[node].min_diff = int(1e9)
			tree[node].best_set1 = Pair{-1, -1}
			tree[node].best_set2 = Pair{L[l], l}
		}
		return
	}
	push(node)
	mid := (l + r) / 2
	update(node*2, l, mid, ql, qr)
	update(node*2+1, mid+1, r, ql, qr)
	merge(node)
}

func solve() {
	n = scanInt()
	v := make([]int, n)
	for i := 0; i < n; i++ {
		v[i] = scanInt()
	}
	p := make([]int, n)
	pos := make([]int, n+1)
	for i := 0; i < n; i++ {
		p[i] = scanInt()
		pos[p[i]] = i + 1
	}

	mushrooms := make([]Mushroom, n)
	for i := 0; i < n; i++ {
		mushrooms[i] = Mushroom{v[i], i + 1}
	}
	sort.Slice(mushrooms, func(i, j int) bool {
		return mushrooms[i].v > mushrooms[j].v
	})

	if cap(L) < n+1 {
		L = make([]int, n+1)
	} else {
		L = L[:n+1]
	}
	for k := 1; k <= n; k++ {
		val := n - k + 1
		if k < val {
			val = k
		}
		L[k] = val
	}

	if cap(tree) < 4*(n+1) {
		tree = make([]Node, 4*(n+1))
	} else {
		tree = tree[:4*(n+1)]
	}
	build(1, 1, n)

	ansVal := int64(0)
	ansK := 1

	for i := 0; i < n; {
		j := i
		curV := mushrooms[i].v
		for j < n && mushrooms[j].v == curV {
			origIdx := mushrooms[j].id
			permPos := pos[origIdx]
			update(1, 1, n, 1, permPos)
			j++
		}

		best := maxPair(tree[1].best_set1, tree[1].best_set2)
		candStr := int64(curV) * int64(best.val)
		if candStr > ansVal {
			ansVal = candStr
			ansK = best.k
		} else if candStr == ansVal {
			if best.k < ansK {
				ansK = best.k
			}
		}
		i = j
	}
	fmt.Fprintf(writer, "%d %d\n", ansVal, ansK)
}

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