답안 #530834

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
530834 2022-02-26T22:32:25 Z Alex_tz307 Lampice (COCI19_lampice) C++17
110 / 110
3089 ms 14692 KB
#include <bits/stdc++.h>

using namespace std;

const int kN = 5e4;
const int mod = 1e9 + 7;
const int base = 29;
string s;
vector<int> g[1 + kN];
int len, m, p[1 + kN], sz[1 + kN], dp[1 + kN], best[1 + kN], h1[1 + kN], h2[1 + kN], nodes[1 + kN];
vector<int> centroids;
bitset<1 + kN> vis;
unordered_multiset<int> preffixes[kN];

int add(int x, int y) {
  x += y;
  if (x >= mod) {
    return x - mod;
  }
  return x;
}

int mult(int x, int y) {
  return (int64_t)x * y % mod;
}

void precalc() {
  p[0] = 1;
  for (int i = 1; i <= kN; ++i) {
    p[i] = mult(p[i - 1], base);
  }
}

void findSize(int u, int par) {
  sz[u] = 1;
  for (int v : g[u]) {
    if (!vis[v] && v != par) {
      findSize(v, u);
      sz[u] += sz[v];
    }
  }
}

int findCentroid(int u, int par, int n) {
  for (int v : g[u]) {
    if (!vis[v] && v != par && sz[v] > n / 2) {
      return findCentroid(v, u, n);
    }
  }
  return u;
}

void dfs(int u, int par) {
  int mx1 = 0, mx2 = 0;
  for (int v : g[u]) {
    if (!vis[v] && v != par) {
      dfs(v, u);
      if (mx1 < dp[v]) {
        mx2 = mx1;
        mx1 = dp[v];
      } else if (mx2 < dp[v]) {
        mx2 = dp[v];
      }
    }
  }
  dp[u] = mx1 + 1;
  best[u] = mx1 + mx2 + 1;
}

void build(int u) {
  findSize(u, 0);
  int c = findCentroid(u, 0, sz[u]);
  centroids.emplace_back(c);
  vis[c] = true;
  dfs(c, 0);
  for (int v : g[c]) {
    if (!vis[v]) {
      build(v);
    }
  }
}

void dfs1(int u, int par, int depth) {
  h1[u] = add(mult(h1[par], base), s[u] - 'a' + 1);
  h2[u] = add(h2[par], mult(p[depth], s[u] - 'a' + 1));
  preffixes[depth + 1].emplace(h1[u]);
  for (int v : g[u]) {
    if (!vis[v] && v != par) {
      dfs1(v, u, depth + 1);
    }
  }
}

void addPaths(int u, int par, int depth) {
  preffixes[depth].emplace(h1[u]);
  for (int v : g[u]) {
    if (!vis[v] && v != par) {
      addPaths(v, u, depth + 1);
    }
  }
}

void removePaths(int u, int par, int depth, bool flag) {
  if (flag || preffixes[depth].count(h1[u])) {
    preffixes[depth].erase(preffixes[depth].find(h1[u]));
  }
  for (int v : g[u]) {
    if (!vis[v] && v != par) {
      removePaths(v, u, depth + 1, flag);
    }
  }
}

bool dfs2(int u, int par, int depth) {
  if (depth == len) {
    return h1[u] == h2[u];
  }
  nodes[m++] = u;
  int d = len - depth + 1;
  if (d <= depth) {
    int split = nodes[m - d];
    if (h1[split] == h2[split]) {
      split = nodes[m - d - 1];
      if (preffixes[d].count(add(h1[u], mod - mult(p[d], h1[split])))) {
        return true;
      }
    }
  }
  for (int v : g[u]) {
    if (!vis[v] && v != par && dfs2(v, u, depth + 1)) {
      return true;
    }
  }
  m -= 1;
  return false;
}

bool solve(int u) {
  for (int c : centroids) {
    vis[c] = true;
    if (best[c] < len) {
      continue;
    }
    dfs1(c, 0, 0);
    for (int v : g[c]) {
      if (!vis[v]) {
        removePaths(v, c, 2, true);
        m = 0;
        nodes[m++] = 0;
        nodes[m++] = c;
        if (dfs2(v, c, 2)) {
          removePaths(c, 0, 1, false);
          return true;
        }
        addPaths(v, c, 2);
      }
    }
    removePaths(c, 0, 1, true);
  }
  return false;
}

bool check(int n) {
  bool ret = solve(1);
  for (int v = 1; v <= n; ++v) {
    vis[v] = false;
  }
  return ret;
}

void testCase() {
  int n;
  cin >> n >> s;
  s = '$' + s;
  bool ok2 = false;
  for (int i = 1; i < n; ++i) {
    int u, v;
    cin >> u >> v;
    g[u].emplace_back(v);
    g[v].emplace_back(u);
    if (s[u] == s[v]) {
      ok2 = true;
    }
  }
  build(1);
  for (int v = 1; v <= n; ++v) {
    vis[v] = false;
  }
  int l = 1, r = (n - 1) / 2, ans1 = 1;
  while (l <= r) {
    int mid = (l + r) / 2;
    len = 2 * mid + 1;
    if (check(n)) {
      ans1 = 2 * mid + 1;
      l = mid + 1;
    } else {
      r = mid - 1;
    }
  }
  int ans2 = 0;
  l = 2, r = n / 2;
  while (l <= r) {
    int mid = (l + r) / 2;
    len = 2 * mid;
    if (check(n)) {
      ans2 = 2 * mid;
      l = mid + 1;
    } else {
      r = mid - 1;
    }
  }
  cout << max({1 + ok2, ans1, ans2}) << '\n';
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  precalc();
  int tests = 1;
  for (int tc = 0; tc < tests; ++tc) {
    testCase();
  }
  return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4428 KB Output is correct
2 Correct 4 ms 4428 KB Output is correct
3 Correct 17 ms 4624 KB Output is correct
4 Correct 17 ms 4712 KB Output is correct
5 Correct 4 ms 4428 KB Output is correct
6 Correct 3 ms 4428 KB Output is correct
7 Correct 3 ms 4428 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1772 ms 13268 KB Output is correct
2 Correct 431 ms 13512 KB Output is correct
3 Correct 386 ms 13736 KB Output is correct
4 Correct 430 ms 14276 KB Output is correct
5 Correct 708 ms 14660 KB Output is correct
6 Correct 229 ms 14692 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3089 ms 10328 KB Output is correct
2 Correct 1516 ms 9956 KB Output is correct
3 Correct 1739 ms 10436 KB Output is correct
4 Correct 883 ms 10688 KB Output is correct
5 Correct 879 ms 9536 KB Output is correct
6 Correct 1602 ms 9192 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4428 KB Output is correct
2 Correct 4 ms 4428 KB Output is correct
3 Correct 17 ms 4624 KB Output is correct
4 Correct 17 ms 4712 KB Output is correct
5 Correct 4 ms 4428 KB Output is correct
6 Correct 3 ms 4428 KB Output is correct
7 Correct 3 ms 4428 KB Output is correct
8 Correct 1772 ms 13268 KB Output is correct
9 Correct 431 ms 13512 KB Output is correct
10 Correct 386 ms 13736 KB Output is correct
11 Correct 430 ms 14276 KB Output is correct
12 Correct 708 ms 14660 KB Output is correct
13 Correct 229 ms 14692 KB Output is correct
14 Correct 3089 ms 10328 KB Output is correct
15 Correct 1516 ms 9956 KB Output is correct
16 Correct 1739 ms 10436 KB Output is correct
17 Correct 883 ms 10688 KB Output is correct
18 Correct 879 ms 9536 KB Output is correct
19 Correct 1602 ms 9192 KB Output is correct
20 Correct 322 ms 9032 KB Output is correct
21 Correct 305 ms 9008 KB Output is correct
22 Correct 905 ms 9172 KB Output is correct
23 Correct 201 ms 9260 KB Output is correct
24 Correct 684 ms 9992 KB Output is correct
25 Correct 1064 ms 10000 KB Output is correct
26 Correct 1736 ms 10620 KB Output is correct
27 Correct 2678 ms 9584 KB Output is correct
28 Correct 248 ms 9408 KB Output is correct
29 Correct 245 ms 9412 KB Output is correct
30 Correct 985 ms 10828 KB Output is correct
31 Correct 1362 ms 9720 KB Output is correct
32 Correct 553 ms 11716 KB Output is correct
33 Correct 174 ms 9240 KB Output is correct