Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define ll long long
- void FIO() {
- #ifndef ONLINE_JUDGE
- freopen("../in.txt", "r", stdin);
- freopen("../out.txt", "w", stdout);
- #endif
- }
- const int N = 1e5 + 5;
- vector<int> adj[N];
- int up[N][20], tin[N], tout[N], depth[N], timer = 1;
- ll hs[N][2][2];
- int arr[N];
- int n;
- ll pw[N][2], invPw[N][2], base[2], mod[2];
- ll power(ll x, ll p, ll MOD = 1) {
- ll ret = 1;
- while (p) {
- if (p & 1) {
- ret = (ret * x) % MOD;
- }
- p >>= 1;
- x = (x * x) % MOD;
- }
- return ret;
- }
- void pre_hash() {
- base[0] = 131, base[1] = 157;
- mod[0] = 1e9 + 7, mod[1] = 1e9 + 9;
- pw[0][0] = pw[0][1] = 1;
- for (int i = 1; i < N; ++i) {
- for (int j = 0; j < 2; ++j) {
- pw[i][j] = pw[i - 1][j] * base[j] % mod[j];
- }
- }
- invPw[N - 1][0] = power(pw[N - 1][0], mod[0] - 2, mod[0]);
- invPw[N - 1][1] = power(pw[N - 1][1], mod[1] - 2, mod[1]);
- for (int i = N - 2; i >= 0; --i) {
- for (int j = 0; j < 2; ++j) {
- invPw[i][j] = base[j] * invPw[i + 1][j] % mod[j];
- }
- }
- }
- void dfs(int u, int p) {
- tin[u] = ++timer;
- up[u][0] = p;
- for (int i = 1; i < 20; ++i) {
- up[u][i] = up[up[u][i - 1]][i - 1];
- }
- // up
- for (int j = 0; j < 2; ++j) {
- hs[u][0][j] = hs[p][0][j] * base[j] % mod[j] + arr[u];
- hs[u][0][j] %= mod[j];
- }
- // down
- for (int j = 0; j < 2; ++j) {
- hs[u][1][j] = hs[p][1][j] + arr[u] * pw[depth[p]][j];
- hs[u][1][j] %= mod[j];
- }
- for (auto v: adj[u]) {
- if (v == p)
- continue;
- depth[v] = depth[u] + 1;
- dfs(v, u);
- }
- tout[u] = timer++;
- }
- bool isAnc(int u, int v) {
- return tin[u] <= tin[v] && tout[v] <= tout[u];
- }
- int lca(int u, int v) {
- if (isAnc(u, v))
- return u;
- if (isAnc(v, u))
- return v;
- for (int l = 19; l >= 0; --l) {
- if (!isAnc(up[u][l], v))
- u = up[u][l];
- }
- return up[u][0];
- }
- void solve() {
- cin >> n;
- for (int i = 1; i <= n; ++i) {
- char c;
- cin >> c;
- arr[i] = (c - 'a' + 1);
- }
- for (int i = 1; i < n; ++i) {
- int u, v;
- cin >> u >> v;
- adj[u].push_back(v);
- adj[v].push_back(u);
- }
- tout[0] = 1e9;
- pre_hash();
- dfs(1, 0);
- int q;
- cin >> q;
- while (q--) {
- int u, v;
- cin >> u >> v;
- array<array<ll, 2>, 2> hss{};
- int lc = lca(u, v);
- for (int i = 0; i < 2; ++i, swap(u, v)) {
- for (int j = 0; j < 2; ++j) {
- int len = depth[u] - depth[lc] + 1;
- hss[i][j] += hs[u][0][j] - (hs[up[lc][0]][0][j] * pw[len][j]) % mod[j] + mod[j];
- hss[i][j] %= mod[j];
- ll down = hs[v][1][j] - hs[lc][1][j] + mod[j];
- down *= invPw[depth[lc]][j];
- down %= mod[j];
- down *= pw[len][j];
- down %= mod[j];
- hss[i][j] += down;
- hss[i][j] %= mod[j];
- }
- }
- cout << (hss[0] == hss[1]) << '\n';
- }
- }
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- cout.tie(nullptr);
- FIO();
- int t = 1;
- // cin >> t;
- while (t--) {
- solve();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement