#include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; const int SIZE = 1 << 10; int pointer = SIZE; char buffer[SIZE]; char Advance() { if (pointer == SIZE) { fread(buffer, 1, SIZE, stdin); pointer = 0; } return buffer[pointer++]; } int Read() { int answer = 0; char ch = Advance(); while (!isdigit(ch)) ch = Advance(); while (isdigit(ch)) { answer = answer * 10 + ch - '0'; ch = Advance(); } return answer; } const int MAXN = 50000; const int MAXNODES = 131072; char s[1 + MAXN]; int from[1 + MAXN], to[1 + MAXN], dp[1 + MAXN], answer[1 + MAXN]; vector > g[1 + MAXN]; int tree[2][1 + MAXNODES], lazy[2][1 + MAXNODES]; void Propagate(int node, int type) { lazy[type][2 * node] += lazy[type][node]; lazy[type][2 * node + 1] += lazy[type][node]; lazy[type][node] = 0; } void Add(int node, int left, int right, int from, int to, int add, int type) { if (from <= left && right <= to) { lazy[type][node] += add; return; } Propagate(node, type); int middle = (left + right) / 2; if (from <= middle) Add(2 * node, left, middle, from, to, add, type); if (middle + 1 <= to) Add(2 * node + 1, middle + 1, right, from, to, add, type); tree[type][node] = max(tree[type][2 * node] + lazy[type][2 * node], tree[type][2 * node + 1] + lazy[type][2 * node + 1]); } int Query(int node, int left, int right, int from, int to, int type) { if (from <= left && right <= to) return tree[type][node] + lazy[type][node]; Propagate(node, type); int middle = (left + right) / 2, answer = 0; if (from <= middle) answer = max(answer, Query(2 * node, left, middle, from, to, type)); if (middle + 1 <= to) answer = max(answer, Query(2 * node + 1, middle + 1, right, from, to, type)); tree[type][node] = max(tree[type][2 * node] + lazy[type][2 * node], tree[type][2 * node + 1] + lazy[type][2 * node + 1]); return answer; } int main() { //freopen("tema.in", "r", stdin); //freopen("tema.out", "w", stdout); int tests; scanf("%d", &tests); for (int test = 1; test <= tests; test++) { int n, m; scanf("%d%d\n", &n, &m); for (int i = 1; i <= m; i++) scanf("%c ", &s[i]); for (int i = 1; i <= m; i++) scanf("%d", &from[i]); for (int i = 1; i <= m; i++) scanf("%d", &to[i]); for (int i = 1; i <= n; i++) { g[i].clear(); dp[i] = 0; } for (int i = 1; i <= m; i++) { if (from[i] < to[i]) { int type = 0; if (s[i] == 'D' || s[i] == 'M') type = 1; g[to[i]].push_back(make_pair(from[i], type)); } answer[i] = -1; } memset(tree, 0, sizeof(tree)); memset(lazy, 0, sizeof(lazy)); for (int i = 2, j = 0; i <= n; i++) { for (auto &it : g[i]) Add(1, 1, n, 1, it.first, 1 ,it.second); dp[i] = max(Query(1, 1, n, 1, i - 1, 0), Query(1, 1, n, 1, i - 1, 1)); while (j < dp[i]) { j++; answer[j] = i; } Add(1, 1, n, i, i, dp[i], 0); Add(1, 1, n, i, i, dp[i], 1); } for (int i = 1; i <= m; i++) printf("%d ", answer[i]); printf("\n"); } return 0; }