#line 2 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/template/procon.hpp" #ifndef DEBUG // 提出時にassertはオフ #ifndef NDEBUG #define NDEBUG #endif // 定数倍高速化 #pragma GCC target("avx2") #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #endif #include using namespace std; using ll = long long; #define ALL(x) (x).begin(), (x).end() template using vec = vector; template inline bool chmax(T &a, const S &b) { return (a < b ? a = b, 1 : 0); } template inline bool chmin(T &a, const S &b) { return (a > b ? a = b, 1 : 0); } template constexpr T INF = 1'000'000'000; template <> constexpr int INF = 1'000'000'000; template <> constexpr ll INF = ll(INF) * INF * 2; #line 2 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/data-structure/fenwickTree.hpp" #line 4 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/data-structure/fenwickTree.hpp" template // 内部では1-baseですが、外からは0-baseに見せてます struct fenwickTree { public: explicit fenwickTree(int size) : _size(size), data(size + 1, 0) { // sizeを超えない2べきを求めておく(lowerBound用) beki_floor = 1; while (beki_floor * 2 <= _size) { beki_floor *= 2; } } // 全てを1にする初期化 void init_all_one() { for (int i = 1; i <= _size; i++) { data[i] = i & (-i); } } // a[index] += x を行う void add(int index, const T &x) { assert(0 <= index && index < _size); int curIndex = index + 1; while (curIndex <= _size) { data[curIndex] += x; // 区間の長さ分だけ番号に足したところを更新していく curIndex += curIndex & (-curIndex); } } // a[index] = xとする void set(int index, const T &x) { assert(0 <= index && index < _size); // +(x - a[index])をするだけ add(index, x - sum(index, index + 1)); } // a[left] + ... + a[right - 1] を求める T sum(int left, int right) const { assert(0 <= left && left <= right && right <= _size); return sumFromFirst(right) - sumFromFirst(left); } // a[0] + ... a[x] >= w なる最小のxを求める(なければx = _size) int lowerBound(int w) const { if (w <= 0) return 0; int x = 0; for (int k = beki_floor; k > 0; k >>= 1) { if (x + k <= _size && data[x + k] < w) { w -= data[x + k]; x += k; } } return x; } private: int _size; std::vector data; // 1-base int beki_floor; // _size以下の最大の2べき // a[0] + ... a[right - 1] の和を求める T sumFromFirst(int right) const { assert(0 <= right && right <= _size); if (right == 0) { return 0; } T ans = 0; int curIndex = right; while (curIndex > 0) { ans += data[curIndex]; // 次に足すべき区間は番号から区間の長さだけ引いたもの curIndex -= curIndex & (-curIndex); } return ans; } }; #line 3 "main.cpp" bool op(bool l, char ope, bool r) { if(ope == 'a') return l & r; if(ope == 'o') return l | r; if(ope == 'x') return l ^ r; if(!l) return true; return r; } bool solve() { int N; cin >> N; vec X(N); for(int i = 0; i < N; i++) { string x; cin >> x; if(x == "True") { X[i] = true; } else { X[i] = false; } } vec Y(N - 1); for(int i = 0; i < N - 1; i++) { string x; cin >> x; Y[i] = x[0]; } vec S(N - 1); for(int &s : S) { cin >> s; } fenwickTree BIT_X(N), BIT_Y(N - 1); BIT_X.init_all_one(); BIT_Y.init_all_one(); for(int s : S) { int x_id_l = BIT_X.lowerBound(s); int x_id_r = BIT_X.lowerBound(s + 1); int y_id = BIT_Y.lowerBound(s); bool ans = op(X[x_id_l], Y[y_id], X[x_id_r]); X[x_id_l] = ans; BIT_X.add(x_id_r, -1); BIT_Y.add(y_id, -1); } return X[BIT_X.lowerBound(1)]; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int T; cin >> T; while(T--) { cout << (solve() ? "True" : "False") << "\n"; } }