Use this to learn the idea, then write your own version.
123 45class Solution {6public:7 vector<bool> palindromePath(int n, vector<vector<int>>& edges, string s, vector<string>& queries) {8 const auto& build_hld = [](const auto& adj, const auto& cb) {9 vector<int> parent(size(adj), -1), depth(size(adj), 0), sz(size(adj), 1), heavy(size(adj), -1), head(size(adj));10 iota(begin(head), end(head), 0);11 vector<tuple<int, int, int>> stk = {{1, 0, -1}};12 while (!empty(stk)) {13 const auto [step, u, p] = stk.back(); stk.pop_back();14 if (step == 1) {15 cb(u, p);16 parent[u] = p;17 depth[u] = (p == -1 ? 0 : depth[p] + 1);18 stk.emplace_back(2, u, p);19 for (const auto& v : adj[u]) {20 if (v == p) {21 continue;22 }23 stk.emplace_back(1, v, u);24 }25 } else if (step == 2) {26 for (const auto& v : adj[u]) {27 if (v == parent[u]) {28 continue;29 }30 sz[u] += sz[v];31 if (heavy[u] == -1 || sz[v] > sz[heavy[u]]) {32 heavy[u] = v;33 }34 }35 }36 }37 int idx = -1;38 vector<int> left(size(adj), -1), right(size(adj), -1);39 stk = {{1, 0, 0}};40 while (!empty(stk)) {41 const auto [step, u, h] = stk.back(); stk.pop_back();42 if (step == 1) {43 head[u] = h;44 left[u] = ++idx;45 stk.emplace_back(2, u, h);46 for (const auto& v : adj[u]) {47 if (v == parent[u] || v == heavy[u]) {48 continue;49 }50 stk.emplace_back(1, v, v);51 }52 if (heavy[u] != -1) {53 stk.emplace_back(1, heavy[u], h);54 }55 } else if (step == 2) {56 right[u] = idx;57 }58 }59 return tuple(parent, depth, head, left, right);60 };61 62 vector<int> prefix(n);63 const auto& callback = [&](int u, int p) {64 prefix[u] = (p != -1 ? prefix[p] : 0) ^ (1 << (s[u] - 'a'));65 };66 67 vector<vector<int>> adj(n);68 for (const auto& e : edges) {69 adj[e[0]].emplace_back(e[1]);70 adj[e[1]].emplace_back(e[0]);71 }72 const auto& [parent, depth, head, left, right] = build_hld(adj, callback);73 const auto& lca = [&](int u, int v) {74 while (head[u] != head[v]) {75 if (depth[head[u]] < depth[head[v]]) {76 swap(u, v);77 }78 u = parent[head[u]];79 }80 return depth[u] < depth[v] ? u : v;81 };82 83 BIT bit(n + 1);84 vector<bool> result;85 for (const auto& q : queries) {86 istringstream iss(q);87 string op;88 int u;89 iss >> op >> u;90 if (op == "update") {91 char c;92 iss >> c;93 const auto& diff = (1 << (s[u] - 'a')) ^ (1 << (c - 'a'));94 if (!diff) {95 continue;96 }97 s[u] = c;98 bit.add(left[u], diff);99 bit.add(right[u] + 1, diff);100 } else {101 int v;102 iss >> v;103 const auto& l = lca(u, v);104 const auto& mask = (prefix[u] ^ bit.query(left[u])) ^ (prefix[v] ^ bit.query(left[v])) ^ (1 << (s[l] - 'a'));105 result.emplace_back((mask & (mask - 1)) == 0);106 }107 }108 return result;109 }110 111private:112 class BIT {113 public:114 BIT(int n) : bit_(n + 1) { 115 }116 117 void add(int i, int val) {118 ++i;119 for (; i < size(bit_); i += lower_bit(i)) {120 bit_[i] ^= val;121 }122 }123 124 int query(int i) const {125 ++i;126 int total = 0;127 for (; i > 0; i -= lower_bit(i)) {128 total ^= bit_[i];129 }130 return total;131 }132 133 private:134 inline int lower_bit(int i) const {135 return i & -i;136 }137 138 vector<int> bit_;139 };140};141 142143144145class Solution2 {146public:147 vector<bool> palindromePath(int n, vector<vector<int>>& edges, string s, vector<string>& queries) {148 vector<vector<int>> adj(n);149 for (const auto& e : edges) {150 adj[e[0]].emplace_back(e[1]);151 adj[e[1]].emplace_back(e[0]);152 }153 TreeInfos tree_infos(adj);154 BIT bit(n + 1);155 for (int u = 0; u < n; ++u) {156 const auto& diff = 1 << (s[u] - 'a');157 bit.add(tree_infos.left(u), diff);158 bit.add(tree_infos.right(u) + 1, diff);159 }160 vector<bool> result;161 for (const auto& q : queries) {162 istringstream iss(q);163 string op;164 int u;165 iss >> op >> u;166 if (op == "update") {167 char c;168 iss >> c;169 const auto& diff = (1 << (s[u] - 'a')) ^ (1 << (c - 'a'));170 if (!diff) {171 continue;172 }173 s[u] = c;174 bit.add(tree_infos.left(u), diff);175 bit.add(tree_infos.right(u) + 1, diff);176 } else {177 int v;178 iss >> v;179 const auto& l = tree_infos.lca(u, v);180 const auto& mask = bit.query(tree_infos.left(u)) ^ bit.query(tree_infos.left(v)) ^ (1 << (s[l] - 'a'));181 result.emplace_back(mask == 0 || (mask & (mask - 1)) == 0);182 }183 }184 return result;185 }186 187private:188 class BIT {189 public:190 BIT(int n) : bit_(n + 1) { 191 }192 193 void add(int i, int val) {194 ++i;195 for (; i < size(bit_); i += lower_bit(i)) {196 bit_[i] ^= val;197 }198 }199 200 int query(int i) const {201 ++i;202 int total = 0;203 for (; i > 0; i -= lower_bit(i)) {204 total ^= bit_[i];205 }206 return total;207 }208 209 private:210 inline int lower_bit(int i) const {211 return i & -i;212 }213 214 vector<int> bit_;215 };216 217 class TreeInfos {218 public:219 TreeInfos(const vector<vector<int>>& adj)220 : L_(size(adj))221 , R_(size(adj))222 , D_(size(adj))223 , P_(size(adj)) {224 225 const int N = size(adj);226 int idx = -1;227 vector<tuple<int, int, int>> stk = {{1, 0, -1}};228 while (!empty(stk)) {229 const auto [step, u, p] = stk.back(); stk.pop_back();230 if (step == 1) {231 D_[u] = (p == -1) ? 1 : D_[p] + 1;232 if (p != -1) {233 P_[u].emplace_back(p); 234 }235 for (int i = 0; i < size(P_[u]); ++i) {236 if (i >= size(P_[P_[u][i]])) {237 break;238 }239 P_[u].emplace_back(P_[P_[u][i]][i]);240 }241 L_[u] = ++idx; 242 stk.emplace_back(2, u, -1);243 for (int i = size(adj[u]) -1; i >= 0; --i) {244 const auto& v = adj[u][i];245 if (v == p) {246 continue;247 }248 stk.emplace_back(1, v, u);249 }250 } else if (step == 2) {251 R_[u] = idx;252 }253 }254 assert(idx == N - 1);255 }256 257 bool is_ancestor(int a, int b) const {258 return L_[a] <= L_[b] && R_[b] <= R_[a];259 }260 261 int lca(int a, int b) const {262 if (D_[a] > D_[b]) {263 swap(a, b);264 }265 if (is_ancestor(a, b)) {266 return a;267 }268 for (int i = size(P_[a]) - 1; i >= 0; --i) { 269 if (i < size(P_[a]) && !is_ancestor(P_[a][i], b)) {270 a = P_[a][i];271 }272 }273 return P_[a][0];274 }275 276 int left(int a) const {277 return L_[a];278 }279 280 int right(int a) const {281 return R_[a];282 }283 284 int depth(int a) const {285 return D_[a];286 }287 288 private:289 vector<int> L_;290 vector<int> R_;291 vector<int> D_;292 vector<vector<int>> P_;293 };294};295