結果
問題 | No.2822 Lights Up! (Tree Edition) |
ユーザー | noya2 |
提出日時 | 2024-07-26 23:58:16 |
言語 | C++23 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 56 ms / 2,000 ms |
コード長 | 21,315 bytes |
コンパイル時間 | 4,292 ms |
コンパイル使用メモリ | 288,060 KB |
実行使用メモリ | 14,200 KB |
最終ジャッジ日時 | 2024-07-26 23:58:26 |
合計ジャッジ時間 | 8,316 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 52 ms
14,200 KB |
testcase_03 | AC | 55 ms
14,200 KB |
testcase_04 | AC | 52 ms
14,200 KB |
testcase_05 | AC | 52 ms
14,200 KB |
testcase_06 | AC | 53 ms
14,072 KB |
testcase_07 | AC | 56 ms
14,072 KB |
testcase_08 | AC | 29 ms
6,724 KB |
testcase_09 | AC | 50 ms
13,744 KB |
testcase_10 | AC | 39 ms
10,132 KB |
testcase_11 | AC | 30 ms
9,532 KB |
testcase_12 | AC | 30 ms
7,316 KB |
testcase_13 | AC | 21 ms
5,376 KB |
testcase_14 | AC | 30 ms
8,260 KB |
testcase_15 | AC | 34 ms
8,608 KB |
testcase_16 | AC | 2 ms
5,376 KB |
testcase_17 | AC | 3 ms
5,376 KB |
testcase_18 | AC | 5 ms
5,376 KB |
testcase_19 | AC | 4 ms
5,376 KB |
testcase_20 | AC | 4 ms
5,376 KB |
testcase_21 | AC | 6 ms
5,376 KB |
testcase_22 | AC | 6 ms
5,376 KB |
testcase_23 | AC | 5 ms
5,376 KB |
testcase_24 | AC | 4 ms
5,376 KB |
testcase_25 | AC | 4 ms
5,376 KB |
testcase_26 | AC | 5 ms
5,376 KB |
testcase_27 | AC | 2 ms
5,376 KB |
testcase_28 | AC | 5 ms
5,376 KB |
testcase_29 | AC | 6 ms
5,376 KB |
testcase_30 | AC | 5 ms
5,376 KB |
testcase_31 | AC | 3 ms
5,376 KB |
testcase_32 | AC | 7 ms
5,376 KB |
testcase_33 | AC | 7 ms
5,376 KB |
testcase_34 | AC | 6 ms
5,376 KB |
testcase_35 | AC | 7 ms
5,376 KB |
testcase_36 | AC | 7 ms
5,376 KB |
testcase_37 | AC | 7 ms
5,376 KB |
testcase_38 | AC | 7 ms
5,376 KB |
testcase_39 | AC | 6 ms
5,376 KB |
testcase_40 | AC | 7 ms
5,376 KB |
testcase_41 | AC | 6 ms
5,376 KB |
testcase_42 | AC | 7 ms
5,376 KB |
testcase_43 | AC | 7 ms
5,376 KB |
testcase_44 | AC | 6 ms
5,376 KB |
testcase_45 | AC | 6 ms
5,376 KB |
testcase_46 | AC | 6 ms
5,376 KB |
testcase_47 | AC | 7 ms
5,376 KB |
testcase_48 | AC | 2 ms
5,376 KB |
testcase_49 | AC | 2 ms
5,376 KB |
testcase_50 | AC | 2 ms
5,376 KB |
testcase_51 | AC | 2 ms
5,376 KB |
testcase_52 | AC | 2 ms
5,376 KB |
testcase_53 | AC | 2 ms
5,376 KB |
testcase_54 | AC | 2 ms
5,376 KB |
testcase_55 | AC | 2 ms
5,376 KB |
testcase_56 | AC | 2 ms
5,376 KB |
testcase_57 | AC | 2 ms
5,376 KB |
testcase_58 | AC | 2 ms
5,376 KB |
testcase_59 | AC | 2 ms
5,376 KB |
testcase_60 | AC | 2 ms
5,376 KB |
testcase_61 | AC | 2 ms
5,376 KB |
testcase_62 | AC | 2 ms
5,376 KB |
testcase_63 | AC | 3 ms
5,376 KB |
testcase_64 | AC | 2 ms
5,376 KB |
testcase_65 | AC | 2 ms
5,376 KB |
testcase_66 | AC | 2 ms
5,376 KB |
testcase_67 | AC | 2 ms
5,376 KB |
testcase_68 | AC | 2 ms
5,376 KB |
testcase_69 | AC | 2 ms
5,376 KB |
testcase_70 | AC | 2 ms
5,376 KB |
testcase_71 | AC | 2 ms
5,376 KB |
testcase_72 | AC | 2 ms
5,376 KB |
testcase_73 | AC | 2 ms
5,376 KB |
testcase_74 | AC | 2 ms
5,376 KB |
testcase_75 | AC | 2 ms
5,376 KB |
testcase_76 | AC | 2 ms
5,376 KB |
testcase_77 | AC | 2 ms
5,376 KB |
testcase_78 | AC | 2 ms
5,376 KB |
testcase_79 | AC | 2 ms
5,376 KB |
testcase_80 | AC | 2 ms
5,376 KB |
testcase_81 | AC | 2 ms
5,376 KB |
testcase_82 | AC | 2 ms
5,376 KB |
testcase_83 | AC | 1 ms
5,376 KB |
testcase_84 | AC | 2 ms
5,376 KB |
testcase_85 | AC | 2 ms
5,376 KB |
testcase_86 | AC | 1 ms
5,376 KB |
testcase_87 | AC | 2 ms
5,376 KB |
testcase_88 | AC | 2 ms
5,376 KB |
testcase_89 | AC | 2 ms
5,376 KB |
testcase_90 | AC | 2 ms
5,376 KB |
testcase_91 | AC | 1 ms
5,376 KB |
testcase_92 | AC | 2 ms
5,376 KB |
testcase_93 | AC | 2 ms
5,376 KB |
testcase_94 | AC | 2 ms
5,376 KB |
testcase_95 | AC | 1 ms
5,376 KB |
testcase_96 | AC | 1 ms
5,376 KB |
testcase_97 | AC | 2 ms
5,376 KB |
testcase_98 | AC | 2 ms
5,376 KB |
testcase_99 | AC | 2 ms
5,376 KB |
testcase_100 | AC | 2 ms
5,376 KB |
testcase_101 | AC | 2 ms
5,376 KB |
testcase_102 | AC | 2 ms
5,376 KB |
testcase_103 | AC | 2 ms
5,376 KB |
testcase_104 | AC | 2 ms
5,376 KB |
testcase_105 | AC | 2 ms
5,376 KB |
testcase_106 | AC | 2 ms
5,376 KB |
testcase_107 | AC | 2 ms
5,376 KB |
testcase_108 | AC | 2 ms
5,376 KB |
testcase_109 | AC | 2 ms
5,376 KB |
testcase_110 | AC | 2 ms
5,376 KB |
testcase_111 | AC | 2 ms
5,376 KB |
testcase_112 | AC | 2 ms
5,376 KB |
testcase_113 | AC | 2 ms
5,376 KB |
testcase_114 | AC | 2 ms
5,376 KB |
testcase_115 | AC | 2 ms
5,376 KB |
testcase_116 | AC | 2 ms
5,376 KB |
testcase_117 | AC | 2 ms
5,376 KB |
testcase_118 | AC | 2 ms
5,376 KB |
testcase_119 | AC | 1 ms
5,376 KB |
testcase_120 | AC | 2 ms
5,376 KB |
testcase_121 | AC | 2 ms
5,376 KB |
testcase_122 | AC | 2 ms
5,376 KB |
testcase_123 | AC | 2 ms
5,376 KB |
testcase_124 | AC | 3 ms
5,376 KB |
testcase_125 | AC | 2 ms
5,376 KB |
testcase_126 | AC | 2 ms
5,376 KB |
testcase_127 | AC | 2 ms
5,376 KB |
testcase_128 | AC | 2 ms
5,376 KB |
testcase_129 | AC | 2 ms
5,376 KB |
testcase_130 | AC | 2 ms
5,376 KB |
testcase_131 | AC | 2 ms
5,376 KB |
testcase_132 | AC | 2 ms
5,376 KB |
testcase_133 | AC | 2 ms
5,376 KB |
testcase_134 | AC | 2 ms
5,376 KB |
testcase_135 | AC | 2 ms
5,376 KB |
testcase_136 | AC | 2 ms
5,376 KB |
testcase_137 | AC | 2 ms
5,376 KB |
testcase_138 | AC | 2 ms
5,376 KB |
testcase_139 | AC | 2 ms
5,376 KB |
testcase_140 | AC | 2 ms
5,376 KB |
testcase_141 | AC | 2 ms
5,376 KB |
testcase_142 | AC | 2 ms
5,376 KB |
testcase_143 | AC | 2 ms
5,376 KB |
ソースコード
#line 2 "/Users/noya2/Desktop/Noya2_library/template/template.hpp" using namespace std; #include<bits/stdc++.h> #line 1 "/Users/noya2/Desktop/Noya2_library/template/inout_old.hpp" namespace noya2 { template <typename T, typename U> ostream &operator<<(ostream &os, const pair<T, U> &p){ os << p.first << " " << p.second; return os; } template <typename T, typename U> istream &operator>>(istream &is, pair<T, U> &p){ is >> p.first >> p.second; return is; } template <typename T> ostream &operator<<(ostream &os, const vector<T> &v){ int s = (int)v.size(); for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i]; return os; } template <typename T> istream &operator>>(istream &is, vector<T> &v){ for (auto &x : v) is >> x; return is; } void in() {} template <typename T, class... U> void in(T &t, U &...u){ cin >> t; in(u...); } void out() { cout << "\n"; } template <typename T, class... U, char sep = ' '> void out(const T &t, const U &...u){ cout << t; if (sizeof...(u)) cout << sep; out(u...); } template<typename T> void out(const vector<vector<T>> &vv){ int s = (int)vv.size(); for (int i = 0; i < s; i++) out(vv[i]); } struct IoSetup { IoSetup(){ cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); cerr << fixed << setprecision(7); } } iosetup_noya2; } // namespace noya2 #line 1 "/Users/noya2/Desktop/Noya2_library/template/const.hpp" namespace noya2{ const int iinf = 1'000'000'007; const long long linf = 2'000'000'000'000'000'000LL; const long long mod998 = 998244353; const long long mod107 = 1000000007; const long double pi = 3.14159265358979323; const vector<int> dx = {0,1,0,-1,1,1,-1,-1}; const vector<int> dy = {1,0,-1,0,1,-1,-1,1}; const string ALP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const string alp = "abcdefghijklmnopqrstuvwxyz"; const string NUM = "0123456789"; void yes(){ cout << "Yes\n"; } void no(){ cout << "No\n"; } void YES(){ cout << "YES\n"; } void NO(){ cout << "NO\n"; } void yn(bool t){ t ? yes() : no(); } void YN(bool t){ t ? YES() : NO(); } } // namespace noya2 #line 2 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp" #line 6 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp" namespace noya2{ unsigned long long inner_binary_gcd(unsigned long long a, unsigned long long b){ if (a == 0 || b == 0) return a + b; int n = __builtin_ctzll(a); a >>= n; int m = __builtin_ctzll(b); b >>= m; while (a != b) { int mm = __builtin_ctzll(a - b); bool f = a > b; unsigned long long c = f ? a : b; b = f ? b : a; a = (c - b) >> mm; } return a << std::min(n, m); } template<typename T> T gcd_fast(T a, T b){ return static_cast<T>(inner_binary_gcd(std::abs(a),std::abs(b))); } long long sqrt_fast(long long n) { if (n <= 0) return 0; long long x = sqrt(n); while ((x + 1) * (x + 1) <= n) x++; while (x * x > n) x--; return x; } template<typename T> T floor_div(const T n, const T d) { assert(d != 0); return n / d - static_cast<T>((n ^ d) < 0 && n % d != 0); } template<typename T> T ceil_div(const T n, const T d) { assert(d != 0); return n / d + static_cast<T>((n ^ d) >= 0 && n % d != 0); } template<typename T> void uniq(std::vector<T> &v){ std::sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); } template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; } template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; } template<typename T> inline bool range(T l, T x, T r){ return l <= x && x < r; } } // namespace noya2 #line 8 "/Users/noya2/Desktop/Noya2_library/template/template.hpp" #define rep(i,n) for (int i = 0; i < (int)(n); i++) #define repp(i,m,n) for (int i = (m); i < (int)(n); i++) #define reb(i,n) for (int i = (int)(n-1); i >= 0; i--) #define all(v) (v).begin(),(v).end() using ll = long long; using ld = long double; using uint = unsigned int; using ull = unsigned long long; using pii = pair<int,int>; using pll = pair<ll,ll>; using pil = pair<int,ll>; using pli = pair<ll,int>; namespace noya2{ /* ~ (. _________ . /) */ } using namespace noya2; #line 2 "c.cpp" #line 2 "/Users/noya2/Desktop/Noya2_library/tree/heavy_light_decomposition.hpp" #line 2 "/Users/noya2/Desktop/Noya2_library/tree/simple_tree.hpp" #line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/csr.hpp" #line 4 "/Users/noya2/Desktop/Noya2_library/data_structure/csr.hpp" #include<ranges> #line 7 "/Users/noya2/Desktop/Noya2_library/data_structure/csr.hpp" namespace noya2::internal { template<class E> struct csr { csr () {} csr (int _n) : n(_n) {} csr (int _n, int m) : n(_n){ start.reserve(m); elist.reserve(m); } // ACL style constructor (do not have to call build) csr (int _n, const std::vector<std::pair<int,E>> &idx_elem) : n(_n), start(_n + 2), elist(idx_elem.size()) { for (auto &[i, e] : idx_elem){ start[i + 2]++; } for (int i = 1; i < n; i++){ start[i + 2] += start[i + 1]; } for (auto &[i, e] : idx_elem){ elist[start[i + 1]++] = e; } prepared = true; } int add(int idx, E elem){ int eid = start.size(); start.emplace_back(idx); elist.emplace_back(elem); return eid; } void build(){ if (prepared) return ; int m = start.size(); std::vector<E> nelist(m); std::vector<int> nstart(n + 2, 0); for (int i = 0; i < m; i++){ nstart[start[i] + 2]++; } for (int i = 1; i < n; i++){ nstart[i + 2] += nstart[i + 1]; } for (int i = 0; i < m; i++){ nelist[nstart[start[i] + 1]++] = elist[i]; } swap(elist,nelist); swap(start,nstart); prepared = true; } const auto operator[](int idx) const { return std::ranges::subrange(elist.begin()+start[idx],elist.begin()+start[idx+1]); } auto operator[](int idx){ return std::ranges::subrange(elist.begin()+start[idx],elist.begin()+start[idx+1]); } const auto operator()(int idx, int l, int r) const { return std::ranges::subrange(elist.begin()+start[idx]+l,elist.begin()+start[idx]+r); } auto operator()(int idx, int l, int r){ return std::ranges::subrange(elist.begin()+start[idx]+l,elist.begin()+start[idx]+r); } int n; std::vector<int> start; std::vector<E> elist; bool prepared = false; }; } // namespace noya2::internal #line 5 "/Users/noya2/Desktop/Noya2_library/tree/simple_tree.hpp" namespace noya2 { struct simple_tree { internal::csr<int> g; simple_tree () {} simple_tree (int _n) : g(_n, (_n - 1)*2) { if (_n == 1){ g.build(); } } void add_edge(int u, int v){ g.add(u, v); int id = g.add(v, u); if (id + 1 == (g.n - 1)*2) g.build(); } void input(int indexed = 1){ for (int i = 0; i < g.n - 1; i++){ int u, v; cin >> u >> v; u -= indexed, v -= indexed; add_edge(u, v); } } void input_parents(int indexed = 1){ for (int i = 0; i < g.n - 1; i++){ int v; cin >> v; v -= indexed; add_edge(i + 1, v); } } const auto operator[](int v) const { return g[v]; } auto operator[](int v){ return g[v]; } int size() const { return g.n; } }; } // namespace noya2 #line 4 "/Users/noya2/Desktop/Noya2_library/tree/heavy_light_decomposition.hpp" namespace noya2 { struct hld_tree { internal::csr<int> g; hld_tree () {} hld_tree (int _n, int _root = 0) : g(_n,(_n - 1)*2), n(_n), root(_root) { if (_n == 1){ build(); } } hld_tree (simple_tree _g, int _root = 0) : g(_g.g), n(_g.g.n), root(_root){ build(); } void add_edge(int u, int v){ g.add(u, v); int id = g.add(v, u); if (id + 1 == (n - 1)*2) build(); } void input(int indexed = 1){ for (int i = 0; i < n - 1; i++){ int u, v; cin >> u >> v; u -= indexed, v -= indexed; add_edge(u, v); } } void input_parents(int indexed = 1){ for (int i = 0; i < n - 1; i++){ int v; cin >> v; v -= indexed; add_edge(i + 1, v); } } int depth(int v) const { return dep[v]; } int parent(int v) const { if (v == root) return -1; return g[v].back(); } int degree(int v) const { return g[v].size(); } int subtree_size(int v) const { return sub[v]; } // if d > dep[v], return -1 int la(int v, int d) const { while (v != -1){ int u = nxt[v]; if (down[v] - d >= down[u]){ v = tour[down[v] - d]; break; } d -= down[v] - down[u] + 1; v = parent(u); } return v; } int lca(int u, int v) const { while (nxt[u] != nxt[v]){ if (down[u] < down[v]) swap(u,v); u = parent(nxt[u]); } return dep[u] < dep[v] ? u : v; } int dist(int u, int v) const { return dep[u] + dep[v] - 2*dep[lca(u,v)]; } // if d > dist(from, to), return -1 int jump(int from, int to, int d) const { int l = lca(from,to); if (d <= dep[from] - dep[l]){ return la(from, d); } d -= dep[from] - dep[l]; if (d <= dep[to] - dep[l]){ return la(to, dep[to] - dep[l] - d); } return -1; } // seg.set(index(v), X[v]); int index(int vertex) const { return down[vertex]; } int index_from_edge(int u, int v) const { return (dep[u] < dep[v] ? down[v] : down[u]); } // X[vertex(i)] = seg.get(i); int vertex(int index) const { return tour[index]; } int subtree_l(int v) const { return down[v]; } int subtree_r(int v) const { return down[v] + sub[v]; } // if r == v, return true bool is_in_subtree(int r, int v) const { return subtree_l(r) <= subtree_l(v) && subtree_l(v) < subtree_r(r); } bool is_in_path(int lv, int mv, int rv) const { return dist(lv,mv) + dist(mv,rv) == dist(lv,rv); } // dist, v1, v2 tuple<int,int,int> diameter(){ int v1 = max_element(dep.begin(),dep.end()) - dep.begin(); vector<int> dist_from_v1(n,numeric_limits<int>::max()); queue<int> que; que.push(v1); dist_from_v1[v1] = 0; while (!que.empty()){ int v = que.front(); que.pop(); for (int u : g[v]){ if (dist_from_v1[u] > dist_from_v1[v]+1){ dist_from_v1[u] = dist_from_v1[v]+1; que.push(u); } } } int v2 = max_element(dist_from_v1.begin(),dist_from_v1.end()) - dist_from_v1.begin(); return make_tuple(dist_from_v1[v2],v1,v2); } // vertex array : vector<int> {from, v1, v2, ... , to} vector<int> path(int from, int to){ int l = lca(from,to); const int sizf = dep[from]-dep[l], sizt = dep[to]-dep[l]; vector<int> pf = {from}, pt; pf.reserve(sizf+1); pt.reserve(sizt); for (int i = 0; i < sizf; i++){ from = parent(from); pf.push_back(from); } for (int i = 0; i < sizt; i++){ pt.push_back(to); to = parent(to); } pf.insert(pf.end(),pt.rbegin(),pt.rend()); return pf; } template<typename F> void path_query(int u, int v, bool vertex, const F &f){ int l = lca(u,v); for (auto [s, t] : ascend(u, l)){ f(t, s + 1); } if (vertex) f(down[l], down[l] + 1); for (auto [s, t] : descend(l, v)){ f(s, t + 1); } } template<typename F> void path_noncommutative_query(int u, int v, bool vertex, const F &f){ int l = lca(u,v); for (auto [s, t] : ascend(u, l)){ f(s + 1, t); // l > r ok } if (vertex) f(down[l],down[l] + 1); for (auto [s, t] : descend(l, v)){ f(s, t + 1); // l > r ok } } template<typename F> void subtree_query(int v, bool vertex, const F &f){ f(down[v] + (vertex ? 0 : 1), down[v] + sub[v]); } // adjacent to v const auto operator[](int v) const { return g[v]; } auto operator[](int v){ return g[v]; } // only child const auto operator()(int v) const { return g(v, 0, degree(v) - (v == root ? 0 : 1)); } auto operator()(int v){ return g(v, 0, degree(v) - (v == root ? 0 : 1)); } private: int n, root; vector<int> dep, sub, down, tour, nxt; // v is ancestor of u. // enumerate [closed] intervals of down ( interval [l, r] may hold l > r ). vector<pair<int,int>> ascend(int u, int v){ vector<pair<int,int>> res; while (nxt[u] != nxt[v]){ res.emplace_back(down[u], down[nxt[u]]); u = parent(nxt[u]); } if (u != v) res.emplace_back(down[u], down[v]+1); return res; } // u is ancestor of v. // enumerate [closed] intervals of down ( interval [l, r] may hold l > r ). vector<pair<int,int>> descend(int u, int v){ if (u == v) return {}; if (nxt[u] == nxt[v]){ return {pair<int,int>(down[u]+1, down[v])}; } vector<pair<int,int>> res = descend(u, parent(nxt[v])); res.emplace_back(down[nxt[v]], down[v]); return res; } void build(){ g.build(); init_sz(); init_hld(); } /* setup dep, sub if v is not root, g[v].back() is parent of v. if v is not leaf (i.e. v has child), g[v].front() is heavy child of v. */ void init_sz(){ dep.resize(n, 0); sub.resize(n, 1); auto dfs = [&](auto sfs, int v, int f) -> void { for (int &u : g[v]){ // only one chance to take parent as u. if (u == f) swap(g[v].back(), u); // twice means u is the last element of g[v], i.e. parent of v. if (u == f) break; dep[u] = dep[v]+1; sfs(sfs, u, v); sub[v] += sub[u]; if (sub[g[v].front()] < sub[u]){ swap(g[v].front(), u); } } }; dfs(dfs, root, -1); } /* setup down, tour, nxt only heavy child c of v, nxt[c] = nxt[v]. for other child c, nxt[c] = c. */ void init_hld(){ down.resize(n); tour.resize(n); nxt.resize(n); nxt[root] = root; int clock = 0; auto dfs = [&](auto sfs, int v) -> void { down[v] = clock++; tour[down[v]] = v; // in case of no child, nothing to do if ((*this)(v).empty()) return ; // heavy child nxt[(*this)(v).front()] = nxt[v]; sfs(sfs, (*this)(v).front()); // other child for (int u : (*this)(v).next()){ nxt[u] = u; sfs(sfs, u); } }; dfs(dfs, root); } public: struct compressed_tree : public simple_tree { using simple_tree::simple_tree; using simple_tree::operator=; hld_tree &g; compressed_tree (hld_tree &g_, vector<int> vs) : g(g_){ auto comp = [&](int lv, int rv){ return g.index(lv) < g.index(rv); }; sort(vs.begin(),vs.end(),comp); int sz = vs.size(); for (int i = 0; i < sz-1; i++){ vs.emplace_back(g.lca(vs[i],vs[i+1])); } sort(vs.begin(),vs.end(),comp); vs.erase(unique(vs.begin(),vs.end()),vs.end()); sz = vs.size(); (*this) = simple_tree(sz); real_vertex = vs; for (int i = 0; i < sz; i++){ g.virtual_vertex[real_vertex[i]] = i; } stack<int> st; st.push(0); for (int i = 1; i < sz; i++){ while (!g.is_in_subtree(real_vertex[st.top()], real_vertex[i])) st.pop(); (*this).add_edge(st.top(),i); st.push(i); } } vector<int> real_vertex; int real_v(int virtual_v) const { return real_vertex[virtual_v]; } int virtual_v(int real_v) const { return g.virtual_vertex[real_v]; } size_t size() const { return real_vertex.size(); } }; compressed_tree compressed_tree_gen(const vector<int> &vs){ if ((int)virtual_vertex.size() != n) virtual_vertex.resize(n); return compressed_tree(*this, vs); } vector<int> virtual_vertex; }; } // namespace noya2 #line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/fenwick_tree.hpp" #line 4 "/Users/noya2/Desktop/Noya2_library/data_structure/fenwick_tree.hpp" namespace noya2{ template <class T> struct fenwick_tree { public: fenwick_tree() : _n(0) {} explicit fenwick_tree(int n_) : _n(n_), data(n_) {} void add(int p, T x) { assert(0 <= p && p < _n); p++; while (p <= _n) { data[p - 1] += x; p += p & -p; } } T sum(int l, int r) { assert(0 <= l && l <= r && r <= _n); return sum(r) - sum(l); } private: int _n; vector<T> data; T sum(int r) { T s = 0; while (r > 0) { s += data[r - 1]; r -= r & -r; } return s; } }; } // namespace noya2 #line 5 "c.cpp" #line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/dsu.hpp" #line 4 "/Users/noya2/Desktop/Noya2_library/data_structure/dsu.hpp" namespace noya2{ struct dsu { public: dsu() : _n(0) {} dsu(int n) : _n(n), parent_or_size(n, -1) {} int merge(int a, int b) { assert(0 <= a && a < _n); assert(0 <= b && b < _n); int x = leader(a), y = leader(b); if (x == y) return x; if (-parent_or_size[x] < -parent_or_size[y]) std::swap(x, y); parent_or_size[x] += parent_or_size[y]; parent_or_size[y] = x; return x; } bool same(int a, int b) { assert(0 <= a && a < _n); assert(0 <= b && b < _n); return leader(a) == leader(b); } int leader(int a) { assert(0 <= a && a < _n); if (parent_or_size[a] < 0) return a; return parent_or_size[a] = leader(parent_or_size[a]); } int size(int a) { assert(0 <= a && a < _n); return -parent_or_size[leader(a)]; } std::vector<std::vector<int>> groups() { std::vector<int> leader_buf(_n), group_size(_n); for (int i = 0; i < _n; i++) { leader_buf[i] = leader(i); group_size[leader_buf[i]]++; } std::vector<std::vector<int>> result(_n); for (int i = 0; i < _n; i++) { result[i].reserve(group_size[i]); } for (int i = 0; i < _n; i++) { result[leader_buf[i]].push_back(i); } result.erase( std::remove_if(result.begin(), result.end(), [&](const std::vector<int>& v) { return v.empty(); }), result.end()); return result; } private: int _n; // root node: -1 * component size // otherwise: parent std::vector<int> parent_or_size; }; } // namespace noya2 #line 7 "c.cpp" void solve(){ int n; in(n); hld_tree g(n); g.input_parents(); vector<int> col(n); { string s; in(s); col[0] = 0; rep(i,n-1){ col[i+1] = (s[i] == '#' ? 1 : 0); } } int q; in(q); dsu d(n); while (q--){ int u, v; in(u,v); u--, v--; d.merge(u,v); } auto gr = d.groups(); vector<int> to(n); iota(all(to),0); for (auto vv : gr){ pii mi(iinf,iinf); for (int v : vv){ chmin(mi,pii(g.depth(v),v)); } for (int v : vv){ to[v] = mi.second; } } vector<int> order(n); iota(all(order),0); sort(all(order),[&](int l, int r){ int dl = g.depth(l); int dr = g.depth(r); if (dl == dr) return l > r; return dl > dr; }); fenwick_tree<int> fen(n); for (int v : order){ int sub = (fen.sum(g.subtree_l(v),g.subtree_r(v)) & 1) ^ col[v]; // out(v,sub,to[v],g.subtree_l(v),g.subtree_r(v)); if (sub != 0 && to[v] != v){ sub ^= 1; fen.add(g.index(v),1); fen.add(g.index(to[v]),1); } if (sub != 0){ no(); return ; } } yes(); } int main(){ int t = 1; //in(t); while (t--) { solve(); } }