답안 #531425

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
531425 2022-02-28T16:47:25 Z Alex_tz307 늑대인간 (IOI18_werewolf) C++17
100 / 100
1051 ms 181972 KB
#include <bits/stdc++.h>
#include "werewolf.h"

using namespace std;
using vi = vector<int>;

const int kN = 2e5;
int n, m, q, stamp;
vi g[kN];
vector<pair<int, int>> t;

struct DSU {
  vi p;

  void init() {
    p.clear();
    p.resize(n);
    iota(p.begin(), p.end(), 0);
  }

  int root(int x) {
    if (x == p[x]) {
      return x;
    }
    return p[x] = root(p[x]);
  }

  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) {
      return;
    }
    p[x] = p.size();
    p[y] = p[x];
    p.emplace_back(p[x]);
    t.emplace_back(y, x);
  }
};

pair<int, int> dfs(int v) {
  if (v < n) {
    t[v].first = t[v].second = stamp;
    stamp += 1;
    return {stamp - 1, stamp - 1};
  }
  pair<int, int> st = dfs(t[v].first);
  pair<int, int> dr = dfs(t[v].second);
  t[v].first = min(st.first, dr.first);
  t[v].second = max(st.second, dr.second);
  return t[v];
}

struct node {
  int sum;
  node* l;
  node* r;

  node() : sum(0), l(nullptr), r(nullptr) {}
};

void build(node* x, int lx, int rx) {
  if (lx == rx) {
    return;
  }
  int mid = (lx + rx) / 2;
  x->l = new node();
  build(x->l, lx, mid);
  x->r = new node();
  build(x->r, mid + 1, rx);
}

void update(node* prev, node* curr, int lx, int rx, int pos) {
  if (lx == rx) {
    curr->sum += 1;
    return;
  }
  int mid = (lx + rx) / 2;
  if (pos <= mid) {
    curr->r = prev->r;
    curr->l = new node();
    update(prev->l, curr->l, lx, mid, pos);
  } else {
    curr->l = prev->l;
    curr->r = new node();
    update(prev->r, curr->r, mid + 1, rx, pos);
  }
  curr->sum = 0;
  if (curr->l) {
    curr->sum += curr->l->sum;
  }
  if (curr->r) {
    curr->sum += curr->r->sum;
  }
}

int query(node* x, int lx, int rx, int st, int dr) {
  if (st <= lx && rx <= dr) {
    return x->sum;
  }
  int mid = (lx + rx) / 2, ans = 0;
  if (st <= mid) {
    ans += query(x->l, lx, mid, st, dr);
  }
  if (mid < dr) {
    ans += query(x->r, mid + 1, rx, st, dr);
  }
  return ans;
}

node* roots[1 + kN];

struct query_t {
  int x1, x2;
  int y1, y2;
  int index;

  bool operator < (const query_t &rhs) const {
    return x2 < rhs.x2;
  }
};

vi check_validity(int N, vi X, vi Y, vi S, vi E, vi L, vi R) {
  n = N;
  m = X.size();
  q = S.size();
  for (int i = 0; i < m; ++i) {
    int u = X[i], v = Y[i];
    g[u].emplace_back(v);
    g[v].emplace_back(u);
  }
  S.emplace_back(0);
  E.emplace_back(0);
  L.emplace_back(0);
  R.emplace_back(n - 1);
  q += 1;
  vi idx(q);
  iota(idx.begin(), idx.end(), 0);
  sort(idx.begin(), idx.end(), [&](const int &i, const int &j) -> bool {
    return L[i] > L[j];
  });
  DSU dsu;
  dsu.init();
  vi rep(q);
  t.resize(n);
  int u = n - 1;
  for (int qq = 0; qq < q; ++qq) {
    int i = idx[qq];
    while (u >= L[i]) {
      for (int v : g[u]) {
        if (v >= L[i]) {
          dsu.unite(u, v);
        }
      }
      u -= 1;
    }
    rep[i] = dsu.root(S[i]);
  }
  stamp = 0;
  dfs(t.size() - 1);
  vector<query_t> queries(q);
  vector<pair<int, int>> points(n);
  for (int i = 0; i < q; ++i) {
    queries[i].x1 = t[rep[i]].first;
    queries[i].x2 = t[rep[i]].second;
    queries[i].index = i;
  }
  for (int i = 0; i < n; ++i) {
    points[i].first = t[i].first;
  }
  dsu.init();
  t.clear();
  t = vector<pair<int, int>>(n);
  sort(idx.begin(), idx.end(), [&](const int &i, const int &j) -> bool {
    return R[i] < R[j];
  });
  u = 0;
  for (int qq = 0; qq < q; ++qq) {
    int i = idx[qq];
    while (u <= R[i]) {
      for (int v : g[u]) {
        if (v <= R[i]) {
          dsu.unite(u, v);
        }
      }
      u += 1;
    }
    rep[i] = dsu.root(E[i]);
  }
  stamp = 0;
  dfs(t.size() - 1);
  for (int i = 0; i < q; ++i) {
    queries[i].y1 = t[rep[i]].first;
    queries[i].y2 = t[rep[i]].second;
  }
  for (int i = 0; i < n; ++i) {
    points[i].second = t[i].first;
  }
  sort(queries.begin(), queries.end());
  sort(points.begin(), points.end());
  vector<int> sol(q - 1);
  roots[0] = new node();
  build(roots[0], 0, n - 1);
  int ptr = 0;
  for (auto it : queries) {
    if (it.index == q - 1) {
      continue;
    }
    while (ptr < n && points[ptr].first <= it.x2) {
      roots[ptr + 1] = new node();
      update(roots[ptr], roots[ptr + 1], 0, n - 1, points[ptr].second);
      ptr += 1;
    }
    int l = 0, r = n - 1, pos = 0;
    while (l <= r) {
      int mid = (l + r) / 2;
      if (points[mid].first >= it.x1) {
        pos = mid;
        r = mid - 1;
      } else {
        l = mid + 1;
      }
    }
    if (query(roots[ptr], 0, n - 1, it.y1, it.y2) - query(roots[pos], 0, n - 1, it.y1, it.y2)) {
      sol[it.index] = 1;
    }
  }
  return sol;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 4992 KB Output is correct
2 Correct 3 ms 4996 KB Output is correct
3 Correct 3 ms 5004 KB Output is correct
4 Correct 3 ms 5000 KB Output is correct
5 Correct 3 ms 4940 KB Output is correct
6 Correct 3 ms 4940 KB Output is correct
7 Correct 4 ms 5000 KB Output is correct
8 Correct 3 ms 4940 KB Output is correct
9 Correct 5 ms 5000 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 4992 KB Output is correct
2 Correct 3 ms 4996 KB Output is correct
3 Correct 3 ms 5004 KB Output is correct
4 Correct 3 ms 5000 KB Output is correct
5 Correct 3 ms 4940 KB Output is correct
6 Correct 3 ms 4940 KB Output is correct
7 Correct 4 ms 5000 KB Output is correct
8 Correct 3 ms 4940 KB Output is correct
9 Correct 5 ms 5000 KB Output is correct
10 Correct 11 ms 6932 KB Output is correct
11 Correct 10 ms 6864 KB Output is correct
12 Correct 13 ms 6964 KB Output is correct
13 Correct 10 ms 6988 KB Output is correct
14 Correct 9 ms 6988 KB Output is correct
15 Correct 14 ms 6988 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 749 ms 172704 KB Output is correct
2 Correct 864 ms 175476 KB Output is correct
3 Correct 842 ms 173720 KB Output is correct
4 Correct 735 ms 173024 KB Output is correct
5 Correct 752 ms 172832 KB Output is correct
6 Correct 716 ms 172688 KB Output is correct
7 Correct 575 ms 172760 KB Output is correct
8 Correct 801 ms 175488 KB Output is correct
9 Correct 772 ms 173816 KB Output is correct
10 Correct 557 ms 172644 KB Output is correct
11 Correct 607 ms 172644 KB Output is correct
12 Correct 659 ms 172724 KB Output is correct
13 Correct 786 ms 175640 KB Output is correct
14 Correct 768 ms 175756 KB Output is correct
15 Correct 760 ms 175608 KB Output is correct
16 Correct 758 ms 175592 KB Output is correct
17 Correct 633 ms 172724 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 4992 KB Output is correct
2 Correct 3 ms 4996 KB Output is correct
3 Correct 3 ms 5004 KB Output is correct
4 Correct 3 ms 5000 KB Output is correct
5 Correct 3 ms 4940 KB Output is correct
6 Correct 3 ms 4940 KB Output is correct
7 Correct 4 ms 5000 KB Output is correct
8 Correct 3 ms 4940 KB Output is correct
9 Correct 5 ms 5000 KB Output is correct
10 Correct 11 ms 6932 KB Output is correct
11 Correct 10 ms 6864 KB Output is correct
12 Correct 13 ms 6964 KB Output is correct
13 Correct 10 ms 6988 KB Output is correct
14 Correct 9 ms 6988 KB Output is correct
15 Correct 14 ms 6988 KB Output is correct
16 Correct 749 ms 172704 KB Output is correct
17 Correct 864 ms 175476 KB Output is correct
18 Correct 842 ms 173720 KB Output is correct
19 Correct 735 ms 173024 KB Output is correct
20 Correct 752 ms 172832 KB Output is correct
21 Correct 716 ms 172688 KB Output is correct
22 Correct 575 ms 172760 KB Output is correct
23 Correct 801 ms 175488 KB Output is correct
24 Correct 772 ms 173816 KB Output is correct
25 Correct 557 ms 172644 KB Output is correct
26 Correct 607 ms 172644 KB Output is correct
27 Correct 659 ms 172724 KB Output is correct
28 Correct 786 ms 175640 KB Output is correct
29 Correct 768 ms 175756 KB Output is correct
30 Correct 760 ms 175608 KB Output is correct
31 Correct 758 ms 175592 KB Output is correct
32 Correct 633 ms 172724 KB Output is correct
33 Correct 797 ms 173716 KB Output is correct
34 Correct 340 ms 41732 KB Output is correct
35 Correct 948 ms 176152 KB Output is correct
36 Correct 764 ms 173408 KB Output is correct
37 Correct 899 ms 175584 KB Output is correct
38 Correct 789 ms 173764 KB Output is correct
39 Correct 727 ms 179300 KB Output is correct
40 Correct 782 ms 181740 KB Output is correct
41 Correct 795 ms 174932 KB Output is correct
42 Correct 634 ms 173232 KB Output is correct
43 Correct 1051 ms 179392 KB Output is correct
44 Correct 785 ms 175404 KB Output is correct
45 Correct 822 ms 179488 KB Output is correct
46 Correct 858 ms 179372 KB Output is correct
47 Correct 817 ms 175724 KB Output is correct
48 Correct 769 ms 175588 KB Output is correct
49 Correct 858 ms 175732 KB Output is correct
50 Correct 729 ms 175664 KB Output is correct
51 Correct 782 ms 181944 KB Output is correct
52 Correct 812 ms 181972 KB Output is correct