// DP[i][0/1] = max animals transported if we drop types 0/1 at position i // DP[0][0] = 0, DP[0][1] = 0 // DP[i][0] = max_{j < i} (DP[j][1] + #[0, i, j]) // where #[0/1, i, j] is the number of animals of types 0/1 that start >= j and end <= i #include #include #include constexpr int MAX_N = 50500; constexpr int MAX_M = 50500; using namespace std; int tc, n, m; char typ[MAX_M]; int start[MAX_M], finish[MAX_M]; vector ending[MAX_N][2]; int dp[MAX_N][2]; int tree[2][4 * MAX_N]; int lazy[2][4 * MAX_N]; int summary[MAX_N]; void set_lazy(int which, int i, int l, int r, int v) { lazy[which][i] += v; tree[which][i] += v; } void push(int which, int i, int l, int r) { if (lazy[which][i]) { if (l < r) { set_lazy(which, 2 * i + 1, l, (l + r) / 2, lazy[which][i]); set_lazy(which, 2 * i + 2, (l + r) / 2 + 1, r, lazy[which][i]); } lazy[which][i] = 0; } } int update(int which, int i, int l, int r, int a, int b, int v) { push(which, i, l, r); if (b < l || r < a) return tree[which][i]; if (l >= a && r <= b) { set_lazy(which, i, l, r, v); } else { tree[which][i] = max(update(which, 2 * i + 1, l, (l + r) / 2, a, b, v), update(which, 2 * i + 2, (l + r) / 2 + 1, r, a, b, v)); } return tree[which][i]; } int query(int which, int i, int l, int r, int a, int b) { push(which, i, l, r); if (b < l || r < a) return 0; if (l >= a && r <= b) { return tree[which][i]; } else { return max(query(which, 2 * i + 1, l, (l + r) / 2, a, b), query(which, 2 * i + 2, (l + r) / 2 + 1, r, a, b)); } } void solve() { scanf(" %d %d", &n, &m); for (int i = 0; i < m; ++i) { scanf(" %c", &typ[i]); } for (int i = 0; i < m; ++i) { scanf(" %d", &start[i]); } for (int i = 0; i < m; ++i) { scanf(" %d", &finish[i]); } for (int i = 1; i <= n; ++i) { for (int which = 0; which <= 1; ++which) { ending[i][which].clear(); } } for (int i = 0; i < m; ++i) { if (start[i] < finish[i]) { int which = (typ[i] == 'E' || typ[i] == 'C') ? 0 : 1; ending[finish[i]][which].push_back(start[i]); } } memset(dp, 0, sizeof(dp)); memset(tree, 0, sizeof(tree)); memset(lazy, 0, sizeof(lazy)); for (int i = 1; i <= n; ++i) { for (int which = 0; which <= 1; ++which) { for (int start : ending[i][which]) { update(which, 0, 0, n, 0, start, 1); } dp[i][which] = query(which, 0, 0, n, 0, i - 1); update(!which, 0, 0, n, i, i, dp[i][which]); } } memset(summary, 0, sizeof(summary)); for (int i = 1; i <= n; ++i) { summary[i] = summary[i - 1]; for (int which = 0; which <= 1; ++which) { summary[i] = max(summary[i], dp[i][which]); } } for (int x = 1; x <= m; ++x) { int ans; if (summary[n] < x) { ans = -1; } else { int lo = 0; int hi = n; while (lo + 1 < hi) { int mid = (lo + hi) / 2; if (summary[mid] < x) { lo = mid; } else { hi = mid; } } ans = hi; } printf("%d%c", ans, x == m ? '\n' : ' '); } } int main() { scanf(" %d", &tc); for (int t = 0; t < tc; ++t) { solve(); } return 0; }