답안 #531438

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
531438 2022-02-28T17:02:50 Z Alex_tz307 늑대인간 (IOI18_werewolf) C++17
100 / 100
955 ms 171436 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(x, y);
  }
};

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]);
  }
  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;
    }
    if (query(roots[ptr], 0, n - 1, it.y1, it.y2) - query(roots[it.x1], 0, n - 1, it.y1, it.y2)) {
      sol[it.index] = 1;
    }
  }
  return sol;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4940 KB Output is correct
2 Correct 3 ms 4996 KB Output is correct
3 Correct 4 ms 5008 KB Output is correct
4 Correct 3 ms 4940 KB Output is correct
5 Correct 3 ms 4940 KB Output is correct
6 Correct 4 ms 4940 KB Output is correct
7 Correct 3 ms 5000 KB Output is correct
8 Correct 3 ms 5068 KB Output is correct
9 Correct 4 ms 4996 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4940 KB Output is correct
2 Correct 3 ms 4996 KB Output is correct
3 Correct 4 ms 5008 KB Output is correct
4 Correct 3 ms 4940 KB Output is correct
5 Correct 3 ms 4940 KB Output is correct
6 Correct 4 ms 4940 KB Output is correct
7 Correct 3 ms 5000 KB Output is correct
8 Correct 3 ms 5068 KB Output is correct
9 Correct 4 ms 4996 KB Output is correct
10 Correct 11 ms 6920 KB Output is correct
11 Correct 10 ms 6988 KB Output is correct
12 Correct 12 ms 6860 KB Output is correct
13 Correct 9 ms 6988 KB Output is correct
14 Correct 9 ms 7036 KB Output is correct
15 Correct 10 ms 7008 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 718 ms 164732 KB Output is correct
2 Correct 834 ms 167556 KB Output is correct
3 Correct 860 ms 166032 KB Output is correct
4 Correct 684 ms 165064 KB Output is correct
5 Correct 721 ms 164984 KB Output is correct
6 Correct 669 ms 164960 KB Output is correct
7 Correct 618 ms 164816 KB Output is correct
8 Correct 881 ms 167684 KB Output is correct
9 Correct 712 ms 165928 KB Output is correct
10 Correct 571 ms 164812 KB Output is correct
11 Correct 632 ms 162616 KB Output is correct
12 Correct 682 ms 164816 KB Output is correct
13 Correct 799 ms 167652 KB Output is correct
14 Correct 876 ms 167744 KB Output is correct
15 Correct 837 ms 167716 KB Output is correct
16 Correct 822 ms 167740 KB Output is correct
17 Correct 595 ms 164768 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4940 KB Output is correct
2 Correct 3 ms 4996 KB Output is correct
3 Correct 4 ms 5008 KB Output is correct
4 Correct 3 ms 4940 KB Output is correct
5 Correct 3 ms 4940 KB Output is correct
6 Correct 4 ms 4940 KB Output is correct
7 Correct 3 ms 5000 KB Output is correct
8 Correct 3 ms 5068 KB Output is correct
9 Correct 4 ms 4996 KB Output is correct
10 Correct 11 ms 6920 KB Output is correct
11 Correct 10 ms 6988 KB Output is correct
12 Correct 12 ms 6860 KB Output is correct
13 Correct 9 ms 6988 KB Output is correct
14 Correct 9 ms 7036 KB Output is correct
15 Correct 10 ms 7008 KB Output is correct
16 Correct 718 ms 164732 KB Output is correct
17 Correct 834 ms 167556 KB Output is correct
18 Correct 860 ms 166032 KB Output is correct
19 Correct 684 ms 165064 KB Output is correct
20 Correct 721 ms 164984 KB Output is correct
21 Correct 669 ms 164960 KB Output is correct
22 Correct 618 ms 164816 KB Output is correct
23 Correct 881 ms 167684 KB Output is correct
24 Correct 712 ms 165928 KB Output is correct
25 Correct 571 ms 164812 KB Output is correct
26 Correct 632 ms 162616 KB Output is correct
27 Correct 682 ms 164816 KB Output is correct
28 Correct 799 ms 167652 KB Output is correct
29 Correct 876 ms 167744 KB Output is correct
30 Correct 837 ms 167716 KB Output is correct
31 Correct 822 ms 167740 KB Output is correct
32 Correct 595 ms 164768 KB Output is correct
33 Correct 792 ms 165760 KB Output is correct
34 Correct 300 ms 30716 KB Output is correct
35 Correct 922 ms 167916 KB Output is correct
36 Correct 775 ms 165292 KB Output is correct
37 Correct 906 ms 167396 KB Output is correct
38 Correct 764 ms 165788 KB Output is correct
39 Correct 708 ms 171316 KB Output is correct
40 Correct 787 ms 170676 KB Output is correct
41 Correct 728 ms 166900 KB Output is correct
42 Correct 602 ms 165356 KB Output is correct
43 Correct 955 ms 169912 KB Output is correct
44 Correct 774 ms 167400 KB Output is correct
45 Correct 754 ms 171436 KB Output is correct
46 Correct 768 ms 171248 KB Output is correct
47 Correct 713 ms 167756 KB Output is correct
48 Correct 742 ms 167856 KB Output is correct
49 Correct 730 ms 167840 KB Output is correct
50 Correct 729 ms 167724 KB Output is correct
51 Correct 762 ms 170932 KB Output is correct
52 Correct 798 ms 170896 KB Output is correct