답안 #648469

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
648469 2022-10-06T16:12:39 Z lto5 Lampice (COCI19_lampice) C++14
17 / 110
5000 ms 11372 KB
#include <bits/stdc++.h>
using namespace std;

#define db(x) cerr << #x << " = " << x << endl
const int N = 50005;
const int BASE = 311;

int n;
string s;
vector <int> g[N];

long long power[N];

int par[N];
int child[N];
int down[N];
bool deleted[N];
int h[N];
long long hash_s[N];
long long rev_hash[N];
vector <int> path;
vector <int> vertices;
map <long long, int> mp;
int ans = 0;
int need;
int rt_cen;

void pre() {
  power[0] = 1;
  for (int i = 1; i < N; i++) {
    power[i] = power[i - 1] * BASE;
  }
}

void read() {
  cin >> n >> s;
  s = ' ' + s;
  for (int i = 2; i <= n; i++) {
    int u, v;
    cin >> u >> v;
    g[u].emplace_back(v);
    g[v].emplace_back(u);
  }
}


void dfs_child (int u, int par = -1) {
  vertices.push_back(u);
  child[u] = 1;
  for (int v : g[u]) {
    if (v == par || deleted[v])
      continue;
    dfs_child(v, u);
    child[u] += child[v];
  }
}

int find_centroid (int u, int n, int par = -1) {
  for (int v : g[u]) {
    if (v == par || deleted[v])
      continue;
    if (child[v] * 2 > n)
      return find_centroid(v, n, u);
  }
  return u;
}

void dfs_add (int u, int delta) {
  h[u] = h[par[u]] + 1;
  hash_s[u] = hash_s[par[u]] * BASE + s[u];
  rev_hash[u] = rev_hash[par[u]] + s[u] * power[h[par[u]]];
  mp[hash_s[u]] += delta;
  if (mp[hash_s[u]] == 0)
    mp.erase(hash_s[u]);
  for (int v : g[u]) {
    if (v == par[u] || deleted[v])
      continue;
    par[v] = u;
    dfs_add(v, delta);
  }
}

bool dfs_calc (int u) {
  path.push_back(u);

  if (h[u] == need && hash_s[u] == rev_hash[u]) {
    return true;
  }


  int rem = need - h[u];
  if (rem == 0) {
    if (hash_s[u] == rev_hash[u]) {
      return true;
    }
  }

  else if (rem > 0) {
    int pos = (int)path.size() - rem - 1;
    if (pos >= 0) {
      int p = path[pos];
      long long need_hash = hash_s[u] - hash_s[par[p]] * power[h[u] - h[p] + 1];
      if (hash_s[p] == rev_hash[p] && mp.count(need_hash)) {
        return true;
      }
    }
  }

  for (int v : g[u]) {
    if (v == par[u] || deleted[v])
      continue;
    par[v] = u;
    if (dfs_calc(v))
      return true;
  }

  path.pop_back();
  return false;
}

void init() {
  for (int u = 1; u <= n; u++) {
    hash_s[u] = 0;
    par[u] = 0;
    deleted[u] = 0;
    child[u] = 0;
    rev_hash[u] = 0;
    h[u] = 0;
  }
  mp.clear();
  path.clear();
}

void reset() {
  for (int v : vertices) {
    hash_s[v] = 0;
    par[v] = 0;
    child[v] = 0;
    rev_hash[v] = 0;
    h[v] = 0;
  }
  vertices.clear();
}

bool centroid (int u) {
  vertices.clear();
  dfs_child(u);
  u = find_centroid(u, child[u]);

  rt_cen = u;

  reset();

  h[u] = 1;
  hash_s[u] = s[u];
  rev_hash[u] = s[u];
  deleted[u] = true;
  path.clear();
  mp.clear();
  path.push_back(u);

  for (int v : g[u]) {
    if (deleted[v])
      continue;
    par[v] = u;
    dfs_add(v, 1);
  }

  for (int v : g[u]) {
    if (deleted[v])
      continue;
    dfs_add(v, -1);
    if (dfs_calc(v))
      return true;
    dfs_add(v, 1);
  }

  for (int v : g[u])
    if (!deleted[v] && centroid(v)) return true;

  return false;
}

bool check (int len) {
  if (len > n)
    return false;
  init();
  if (len == 1)
    return true;
  need = len;
  return centroid(1);
}

void bs (int delta) {
  int L = 0, R = (n + 1) / 2;
  while (L <= R) {
    int mid = (L + R) / 2;
    if (check(2 * mid + delta))
      ans = max(ans, 2 * mid + delta), L = mid + 1;
    else
      R = mid - 1;
  }
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0); cout.tie(0);

//  freopen("input.txt", "r", stdin);

  pre();
  read();

  if (n == 1) {
    cout << 1;
    return 0;
  }

  if (n == 2) {
    cout << (s[1] == s[2] ? 2 : 1);
    return 0;
  }

  bs(0);
  bs(1);
  cout << ans;

  return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 1876 KB Output is correct
2 Correct 21 ms 1876 KB Output is correct
3 Correct 104 ms 2132 KB Output is correct
4 Correct 86 ms 2108 KB Output is correct
5 Correct 2 ms 1876 KB Output is correct
6 Correct 2 ms 1876 KB Output is correct
7 Correct 2 ms 1876 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5050 ms 11372 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5050 ms 9820 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 1876 KB Output is correct
2 Correct 21 ms 1876 KB Output is correct
3 Correct 104 ms 2132 KB Output is correct
4 Correct 86 ms 2108 KB Output is correct
5 Correct 2 ms 1876 KB Output is correct
6 Correct 2 ms 1876 KB Output is correct
7 Correct 2 ms 1876 KB Output is correct
8 Execution timed out 5050 ms 11372 KB Time limit exceeded
9 Halted 0 ms 0 KB -