Submission #390252

# Submission time Handle Problem Language Result Execution time Memory
390252 2021-04-15T16:09:36 Z Hegdahl Werewolf (IOI18_werewolf) C++17
100 / 100
2627 ms 181044 KB
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#include "werewolf.h"
#include <bits/stdc++.h>

#define ar array

using namespace std;

struct reachability_tree {
  vector<int> boss, under, tup, time_of, lk, rk, leftmost, rightmost;

  vector<int> up[20];

  int find(int i) {
    return i == boss[i] ? i : boss[i] = find(boss[i]);
  }

  void unite(int i, int j) {
    i = find(i), j = find(j);
    if (i == j) return;

    if (under[i] < under[j]) swap(i, j);
    under[i] += under[j];
    boss[j] = i;
    tup[i] = max(tup[i], tup[j]);
  }

  int nxt_new_node;
  void add_edge(int i, int j, int t) {
    i = find(i), j = find(j);
    if (i == j) return;
    i = tup[i];
    j = tup[j];

    lk[nxt_new_node] = i;
    rk[nxt_new_node] = j;
    time_of[nxt_new_node] = t;

    unite(i, nxt_new_node);
    unite(j, nxt_new_node);

    ++nxt_new_node;
  }

  vector<int> tour, pof;
  void dfs(int cur) {
    if (lk[cur] != -1) {
      dfs(lk[cur]);
      leftmost[cur] = leftmost[lk[cur]];
      up[0][lk[cur]] = cur;
    } else leftmost[cur] = tour.size();

    pof[cur] = tour.size();
    tour.push_back(cur);
    up[0][cur] = cur;

    if (rk[cur] != -1) {
      dfs(rk[cur]);
      rightmost[cur] = rightmost[rk[cur]];
      up[0][rk[cur]] = cur;
    } else rightmost[cur] = tour.size()-1;
  }

  ar<int, 2> qry(int i, int t) {
    for (int lvl = 19; lvl >= 0; --lvl)
      if (time_of[up[lvl][i]] <= t)
        i = up[lvl][i];
    return {leftmost[i], rightmost[i]};
  }

  reachability_tree(int n, vector<ar<int, 3>> e) {
    boss.resize(2*n);
    under.resize(2*n, 1);
    tup.resize(2*n);
    time_of.resize(2*n);
    lk.resize(2*n, -1);
    rk.resize(2*n, -1);
    pof.resize(2*n, -1);
    rightmost.resize(2*n, -1);
    leftmost.resize(2*n, -1);

    iota(boss.begin(), boss.end(), 0);
    iota(tup.begin(), tup.end(), 0);

    nxt_new_node = n;

    for (auto [w, i, j] : e)
      add_edge(i, j, w);

    for (int lvl = 0; lvl < 20; ++lvl) {
      up[lvl].resize(2*n);
      iota(up[lvl].begin(), up[lvl].end(), 0);
    }

    for (int i = 0; i < 2*n; ++i)
      if (i == find(i))
        dfs(tup[i]);

    for (int lvl = 0; lvl < 19; ++lvl)
      for (int i = 0; i < 2*n; ++i)
        up[lvl+1][i] = up[lvl][up[lvl][i]];

    /*cout << "tour: ";
    for (int x : tour)
      cerr << x << ' ';
    cerr << '\n';
    cout << "pof: ";
    for (int x : pof)
      cerr << x << ' ';
    cerr << '\n';
    cout << "leftmost: ";
    for (int l : leftmost)
      cerr << l << ' ';
    cerr << '\n';
    cout << "rightmost: ";
    for (int r : rightmost)
      cerr << r << ' ';
    cerr << '\n';*/
  }
};

const int mxN = 4e5;
const int lg2 = __lg(mxN-1)+1;
const int offset = 1<<lg2;
vector<int> values[2*offset];

void insert(int i, int j) {
  i += offset;
  do {
    values[i].push_back(j);
  } while (i /= 2);
}

bool check(int I, int lo, int hi) {
  return lower_bound(values[I].begin(), values[I].end(), lo)
      != upper_bound(values[I].begin(), values[I].end(), hi);
}

bool qry(int li, int hi, int lj, int hj) {
  li += offset-1;
  hi += offset+1;

  while (li+1 < hi) {
    if (li%2 == 0) if (check(li+1, lj, hj)) return true;
    if (hi%2 == 1) if (check(hi-1, lj, hj)) return true;
    li /= 2, hi /= 2;
  }

  return false;
}

vector<int> check_validity(int n, vector<int> e0, vector<int> e1,
                                vector<int> q0, vector<int> q1,
                                vector<int> ls, vector<int> rs) {
  int m = e0.size();
  int q = q0.size();

  vector<ar<int, 3>> e(m);
  for (int mm = 0; mm < m; ++mm)
    e[mm] = {max(e0[mm], e1[mm]), e0[mm], e1[mm]};

  sort(e.begin(), e.end());
  reachability_tree lo_tree(n, e);
  for (auto &[w, i, j] : e)
    w = n-min(i, j);
  sort(e.begin(), e.end());
  reachability_tree hi_tree(n, e);

  for (int nn = 0; nn < n; ++nn) {
    int i = lo_tree.pof[nn];
    int j = hi_tree.pof[nn];
    insert(i, j);
  }

  for (int i = 2*offset-1; i > 0; --i)
    sort(values[i].begin(), values[i].end());

  vector<int> ans(q);
  for (int i = 0; i < q; ++i) {
    //cerr << '\n';
    //cerr << q0[i] << ' ' << q1[i] << ' ' << ls[i] << ' ' << rs[i] << '\n';
    auto [ll, lr] = lo_tree.qry(q1[i], rs[i]);
    auto [hl, hr] = hi_tree.qry(q0[i], n-ls[i]);

    ans[i] = qry(ll, lr, hl, hr);
  }

  return ans;
}
# Verdict Execution time Memory Grader output
1 Correct 25 ms 24908 KB Output is correct
2 Correct 20 ms 24992 KB Output is correct
3 Correct 20 ms 24952 KB Output is correct
4 Correct 20 ms 24908 KB Output is correct
5 Correct 20 ms 24996 KB Output is correct
6 Correct 21 ms 24880 KB Output is correct
7 Correct 22 ms 24944 KB Output is correct
8 Correct 20 ms 24992 KB Output is correct
9 Correct 23 ms 24920 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 25 ms 24908 KB Output is correct
2 Correct 20 ms 24992 KB Output is correct
3 Correct 20 ms 24952 KB Output is correct
4 Correct 20 ms 24908 KB Output is correct
5 Correct 20 ms 24996 KB Output is correct
6 Correct 21 ms 24880 KB Output is correct
7 Correct 22 ms 24944 KB Output is correct
8 Correct 20 ms 24992 KB Output is correct
9 Correct 23 ms 24920 KB Output is correct
10 Correct 33 ms 27084 KB Output is correct
11 Correct 34 ms 27084 KB Output is correct
12 Correct 33 ms 27104 KB Output is correct
13 Correct 35 ms 27212 KB Output is correct
14 Correct 35 ms 27176 KB Output is correct
15 Correct 34 ms 27240 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2184 ms 170512 KB Output is correct
2 Correct 1644 ms 173688 KB Output is correct
3 Correct 1630 ms 171732 KB Output is correct
4 Correct 1966 ms 170876 KB Output is correct
5 Correct 2130 ms 170616 KB Output is correct
6 Correct 2320 ms 170496 KB Output is correct
7 Correct 2066 ms 170384 KB Output is correct
8 Correct 1391 ms 173576 KB Output is correct
9 Correct 1218 ms 171560 KB Output is correct
10 Correct 918 ms 170760 KB Output is correct
11 Correct 1000 ms 170504 KB Output is correct
12 Correct 1395 ms 170448 KB Output is correct
13 Correct 2007 ms 173592 KB Output is correct
14 Correct 2045 ms 173580 KB Output is correct
15 Correct 2036 ms 173700 KB Output is correct
16 Correct 2009 ms 173628 KB Output is correct
17 Correct 2061 ms 170472 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 25 ms 24908 KB Output is correct
2 Correct 20 ms 24992 KB Output is correct
3 Correct 20 ms 24952 KB Output is correct
4 Correct 20 ms 24908 KB Output is correct
5 Correct 20 ms 24996 KB Output is correct
6 Correct 21 ms 24880 KB Output is correct
7 Correct 22 ms 24944 KB Output is correct
8 Correct 20 ms 24992 KB Output is correct
9 Correct 23 ms 24920 KB Output is correct
10 Correct 33 ms 27084 KB Output is correct
11 Correct 34 ms 27084 KB Output is correct
12 Correct 33 ms 27104 KB Output is correct
13 Correct 35 ms 27212 KB Output is correct
14 Correct 35 ms 27176 KB Output is correct
15 Correct 34 ms 27240 KB Output is correct
16 Correct 2184 ms 170512 KB Output is correct
17 Correct 1644 ms 173688 KB Output is correct
18 Correct 1630 ms 171732 KB Output is correct
19 Correct 1966 ms 170876 KB Output is correct
20 Correct 2130 ms 170616 KB Output is correct
21 Correct 2320 ms 170496 KB Output is correct
22 Correct 2066 ms 170384 KB Output is correct
23 Correct 1391 ms 173576 KB Output is correct
24 Correct 1218 ms 171560 KB Output is correct
25 Correct 918 ms 170760 KB Output is correct
26 Correct 1000 ms 170504 KB Output is correct
27 Correct 1395 ms 170448 KB Output is correct
28 Correct 2007 ms 173592 KB Output is correct
29 Correct 2045 ms 173580 KB Output is correct
30 Correct 2036 ms 173700 KB Output is correct
31 Correct 2009 ms 173628 KB Output is correct
32 Correct 2061 ms 170472 KB Output is correct
33 Correct 2478 ms 171224 KB Output is correct
34 Correct 555 ms 59264 KB Output is correct
35 Correct 2404 ms 173868 KB Output is correct
36 Correct 2364 ms 171104 KB Output is correct
37 Correct 2421 ms 173088 KB Output is correct
38 Correct 2418 ms 171568 KB Output is correct
39 Correct 2627 ms 176736 KB Output is correct
40 Correct 1838 ms 180628 KB Output is correct
41 Correct 1666 ms 172496 KB Output is correct
42 Correct 1157 ms 171044 KB Output is correct
43 Correct 1748 ms 178244 KB Output is correct
44 Correct 2052 ms 173056 KB Output is correct
45 Correct 1478 ms 177168 KB Output is correct
46 Correct 1243 ms 176764 KB Output is correct
47 Correct 2021 ms 174016 KB Output is correct
48 Correct 2041 ms 173592 KB Output is correct
49 Correct 2045 ms 173936 KB Output is correct
50 Correct 2079 ms 173600 KB Output is correct
51 Correct 1574 ms 180916 KB Output is correct
52 Correct 1571 ms 181044 KB Output is correct