package main import "fmt" import "io/ioutil" import "math" import "os" import "sort" func main() { T := ScanInt(1, 10) for t := 0; t < T; t++ { doit() } } type Animal struct { kind, s, d int } type End struct { where, score, unseen int } func doit() { NewLine() M := ScanInt(1, 5e4) N := ScanInt(1, 5e4) A := make([]Animal, N) NewLine() for k := range A { switch ScanBytes(1, 1)[0] { case 'E', 'C': A[k].kind = 0 case 'D', 'M': A[k].kind = 1 default: Assert(false) } } NewLine() for k := range A { A[k].s = ScanInt(1, M) - 1 } NewLine() for k := range A { A[k].d = ScanInt(1, M) - 1 Assert(A[k].d != A[k].s) } saveN := N N = 0 for _, a := range A { if a.s < a.d { A[N] = a N++ } } A = A[:N] sort.Slice(A, func(i, j int) bool { return A[i].s < A[j].s }) var byd [2][][]int byd[0] = make([][]int, M) byd[1] = make([][]int, M) var unseen [2]int for _, a := range A { list := &byd[a.kind][a.d] *list = append(*list, a.s) unseen[a.kind]++ } best := make([]int, M) var ends [2][]End ends[0] = append(ends[0], End{ 0, 0, unseen[1] }) ends[1] = append(ends[1], End{ 0, 0, unseen[0] }) seendone := 0 for m := 0; m < M; m++ { var using = [2]int{ -1, -1 } for k, bydk := range byd { bydkm := bydk[m] if len(bydkm) == 0 { continue } otherends := ends[1-k] last := bydkm[len(bydkm)-1] after := sort.Search(len(otherends), func(i int) bool { return otherends[i].where > last }) count := 0 keep := after j := len(bydkm) - 1 for i := after - 1; i >= 0; i-- { endi := otherends[i] for j >= 0 && bydkm[j] >= endi.where { count++ j-- } endi.score += count endi.unseen -= count Assert(endi.unseen >= 0) if endi.score > using[k] { using[k] = endi.score } if keep == len(otherends) || endi.unseen != otherends[keep].unseen { keep-- otherends[keep] = endi } else if endi.score > otherends[keep].score { otherends[keep] = endi } } ends[1-k] = otherends[keep:] } bestm := 0 if m > 0 { bestm = best[m-1] for _, u := range using { if u > bestm { bestm = u } } } best[m] = bestm for k, u := range using { if u == bestm && using[1-k] != bestm { ek := ends[k] /* for { ekl := len(ek) if ekl == 0 { break } prev := ek[ekl-1] if starting[1-k].SumRange(prev, m) > bestm - best[prev] { break } ek = ek[:ekl-1] } */ ends[k] = append(ek, End{ m, bestm, unseen[1-k] }) } } for seendone < N { a := A[seendone] Assert(a.s >= m) if a.s > m { break } unseen[a.kind]-- seendone++ } } m := 0 for n := 1; n <= saveN; n++ { if n > 1 { fmt.Print(" ") } for m < M && best[m] < n { m++ } if m == M { fmt.Print(-1) } else { fmt.Print(m + 1) } } fmt.Println() } func Assert(condition bool) { if !condition { panic("assertion failed") } } func NewLine() { if CheckInput { for n, b := range RemainingInput { if b != ' ' && b != '\t' && b != '\r' { Assert(b == '\n') RemainingInput = RemainingInput[n+1:] return } } Assert(false) } } func ScanBytes(short, long int) []byte { token := ScanToken() Assert(short <= len(token) && len(token) <= long) return token } func ScanInt(low, high int) int { return int(ScanInt64(int64(low), int64(high))) } var RemainingInput []byte func init() { var e error RemainingInput, e = ioutil.ReadAll(os.Stdin) if e != nil { panic(e) } } var CheckInput = true func ScanToken() []byte { for n, b := range RemainingInput { if b == ' ' || b == '\t' || b == '\r' { continue } if b == '\n' { Assert(!CheckInput) continue } RemainingInput = RemainingInput[n:] break } Assert(len(RemainingInput) > 0) n := 1 for ; n < len(RemainingInput); n++ { b := RemainingInput[n] if b == ' ' || b == '\t' || b == '\r' || b == '\n' { break } } token := RemainingInput[:n] RemainingInput = RemainingInput[n:] return token } func ScanInt64(low, high int64) int64 { x := Btoi(ScanToken()) Assert(low <= x && x <= high || !CheckInput) return x } func Btoi(s []byte) int64 { if s[0] == '-' { x := Btou(s[1:]) Assert(x <= - math.MinInt64) return - int64(x) } else { x := Btou(s) Assert(x <= math.MaxInt64) return int64(x) } } func Btou(s []byte) uint64 { Assert(len(s) > 0) var x uint64 for _, d := range s { Assert('0' <= d && d <= '9') d -= '0' if x >= math.MaxUint64 / 10 { Assert(x == math.MaxUint64 / 10 && d <= math.MaxUint64 % 10) } x = x * 10 + uint64(d) } return x }