import std.conv, std.functional, std.range, std.stdio, std.string; import std.algorithm, std.array, std.bigint, std.bitmanip, std.complex, std.container, std.math, std.mathspecial, std.numeric, std.regex, std.typecons; import core.bitop; class EOFException : Throwable { this() { super("EOF"); } } string[] tokens; string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; } int readInt() { return readToken.to!int; } long readLong() { return readToken.to!long; } real readReal() { return readToken.to!real; } bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } } bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } } int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; } int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); } int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); } int lis(const(int[]) as) { int[] seq; foreach (a; as) { const pos = seq.lowerBound(a); if (pos == seq.length) { seq ~= a; } else { seq[pos] = a; } } return cast(int)(seq.length); } // (left non-C) < (right C) int[] sub(const(int) N, const(int) A, const(string) S, const(char) C) { assert(2 <= A); assert(A <= N); auto tail = new bool[N + 1]; { bool hasC; foreach_reverse (i; 0 .. N) { tail[i] = tail[i + 1]; if (S[i] == C) { hasC = true; } else { if (hasC) { tail[i] = true; } } } } foreach (k; 0 .. N) { if (k + (tail[k] ? 2 : 1) == A) { auto ps = new int[N]; ps[] = -1; int val = 0; foreach (i; 0 .. k) { ps[i] = val++; } foreach_reverse (i; k .. N) if (S[i] != C) { ps[i] = val++; } foreach_reverse (i; k .. N) if (S[i] == C) { ps[i] = val++; } return ps; } } assert(false); } alias Result = Tuple!(int[], "xs", int[], "ys"); Result entangle(const(int) N, const(string) S, const(int[]) ps, const(int[]) qs) { auto posP = new int[N]; auto posQ = new int[N]; posP[] = -1; posQ[] = -1; foreach (i; 0 .. N) { posP[ps[i]] = i; posQ[qs[i]] = i; } auto xs = new int[N]; auto ys = new int[N]; xs[] = -1; ys[] = -1; int val; int k; foreach (j; 0 .. N) { for (; k < N; ++k) { const i = posQ[k]; if (~xs[i]) { if (S[i] == 'a') { assert(false); } else { ys[i] = val++; } } else { if (S[i] == 'a') { ys[i] = val++; } else { break; } } } xs[posP[j]] = val++; } return Result(xs, ys); } Result solve(const(int) N, const(int) A, const(int) B, const(string) S) { int[] xs, ys; if (A == 1) { // (left b) > (right a) ==> IS: a...ab...b auto sumA = new int[N + 1]; foreach (i; 0 .. N) { sumA[i + 1] = sumA[i] + ((S[i] == 'a') ? 1 : 0); } foreach (k; 0 .. N + 1) { const l = sumA[k]; const r = (N - k) - (sumA[N] - sumA[k]); if (1 <= B && B <= l + r) { auto ps = iota(N).array; auto qs = new int[N]; qs[] = -1; int val; foreach_reverse (i; k .. N) if (S[i] == 'a') { qs[i] = val++; } { int cnt; foreach (i; 0 .. N) if ((i < k) == (S[i] == 'a')) { qs[i] = val + ((cnt < B - 1) ? cnt : (l + r - 1 - (cnt - (B - 1)))); } } foreach_reverse (i; 0 .. k) if (S[i] == 'b') { qs[i] = val++; } auto res = entangle(N, S, ps, qs); xs = res.xs; ys = res.ys; break; } } } else if (B == 1) { auto res = solve(N, B, A, S.map!(c => cast(char)('a' ^ 'b' ^ c)).array); xs = res.ys; ys = res.xs; } else { const ps = sub(N, A, S, 'a'); const qs = sub(N, B, S, 'b'); auto res = entangle(N, S, ps, qs); xs = res.xs; ys = res.ys; } return Result(xs, ys); } void main() { /* debug { foreach (n; 1 .. 6 + 1) { auto can = new char[][][](1 << n, n + 1, n + 1); foreach (h; 0 .. 1 << n) foreach (a; 0 .. n + 1) { can[h][a][] = '0'; } auto perm = iota(2 * n).array; do { int h; foreach (i; 0 .. n) { if (perm[i] > perm[n + i]) { h |= 1 << i; } } const a = lis(perm[0 .. n]); const b = lis(perm[n .. 2 * n]); can[h][a][b] = '1'; } while (perm.nextPermutation); foreach (h; 0 .. 1 << n) { const string pat = iota(n).map!(i => "01"[h >> i & 1]).array; writeln(pat, " ", -[h]); foreach (a; 1 .. n + 1) foreach (b; 1 .. n + 1) if (can[h][a][b] == '0') { stderr.writeln(pat, " ", a, " ", b); stderr.flush; assert(a == 1 || b == 1); } } stdout.flush; stderr.flush; } return; } */ try { for (; ; ) { const numCases = readInt; foreach (caseId; 0 .. numCases) { const N = readInt; const A = readInt; const B = readInt; const S = readToken; const ans = solve(N, A, B, S); if (ans.xs) { writeln("Yes"); foreach (i; 0 .. N) { if (i) write(" "); write(ans.xs[i] + 1); } writeln; foreach (i; 0 .. N) { if (i) write(" "); write(ans.ys[i] + 1); } writeln; } else { writeln("No"); } } } } catch (EOFException e) { } }