답안 #868035

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
868035 2023-10-30T09:28:49 Z vjudge1 늑대인간 (IOI18_werewolf) C++17
0 / 100
1668 ms 218604 KB
#include "werewolf.h"
using namespace std;
#include <bits/stdc++.h>
class tree_t {
       public:
        int N, timer;
        vector<int> tin, tout, a;
        vector<vector<int>> g, par;

        tree_t(int N = 0) : N(N), tin(N), tout(N), g(N), timer(0), a(N), par(__lg(N) + 1, vector<int>(N)) {}

        void dfs(int u, int p) {
                tin[u] = timer++;
                par[0][u] = p;
                for (int i = 1; i <= __lg(N); i++) par[i][u] = par[i - 1][par[i - 1][u]];
                for (int v : g[u]) dfs(v, u);
                tout[u] = timer;
        }
};

class segtree_t {
       public:
        segtree_t *left, *right;
        vector<int> val;
        int l, r, m;

        segtree_t(int l, int r) : l(l), r(r), m(l + r >> 1), val() {
                if (l == r) return;
                left = new segtree_t(l, m);
                right = new segtree_t(m + 1, r);
        }

        void Update(int x, int y) {
                val.emplace_back(y);
                if (l == r) return;
                if (x <= m) {
                        left->Update(x, y);
                } else {
                        right->Update(x, y);
                }
        }

        void Sort() {
                sort(val.begin(), val.end());
                if (l == r) return;
                left->Sort(), right->Sort();
        }

        bool Get(int lx, int rx, int ly, int ry) {
                if (l > rx || r < lx) return 0;
                if (lx <= l && r <= rx) return lower_bound(val.begin(), val.end(), ry) - lower_bound(val.begin(), val.end(), ly);
                return left->Get(lx, rx, ly, ry) || right->Get(lx, rx, ly, ry);
        }
};

std::vector<int> check_validity(int N, std::vector<int> X, std::vector<int> Y,
                                std::vector<int> S, std::vector<int> E,
                                std::vector<int> L, std::vector<int> R) {
        int M = X.size(), Q = L.size();
        vector<vector<int>> adj(N);

        for (int i = 0; i < M; i++) adj[X[i]].emplace_back(Y[i]);
        for (int i = 0; i < M; i++) adj[Y[i]].emplace_back(X[i]);

        vector<int> par(N, -1);

        function<int(int)> root = [&](int u) { return par[u] < 0 ? u : (par[u] = root(par[u])); };

        int cur_N = N;

        tree_t TL(N * 2 - 1), TR(N * 2 - 1);

        for (int i = 0; i < N; i++) {
                TL.a[i] = i;
                for (int j : adj[i]) {
                        if (j >= i) continue;
                        int u = root(i), v = root(j);
                        if (u == v) continue;
                        par.emplace_back(par[u] + par[v]);
                        TL.g[cur_N].emplace_back(u);
                        TL.g[cur_N].emplace_back(v);
                        TL.a[cur_N] = i;
                        par[u] = par[v] = cur_N++;
                }
        }

        par = vector<int>(N, -1);
        cur_N = N;

        for (int i = N - 1; i >= 0; i--) {
                TR.a[i] = i;
                for (int j : adj[i]) {
                        if (j <= i) continue;
                        int u = root(i), v = root(j);
                        if (u == v) continue;
                        par.emplace_back(par[u] + par[v]);
                        TR.g[cur_N].emplace_back(u);
                        TR.g[cur_N].emplace_back(v);
                        TR.a[cur_N] = i;
                        par[u] = par[v] = cur_N++;
                }
        }

        const int Root = N * 2 - 1;

        TL.dfs(Root - 1, Root - 1);
        TR.dfs(Root - 1, Root - 1);
        segtree_t *tree = new segtree_t(0, Root);

        for (int i = 0; i < N; i++) {
                int x = TL.tin[i], y = TR.tin[i];
                tree->Update(x, y);
        }
        tree->Sort();

        vector<int> ans;

        for (int i = 0; i < Q; i++) {
                int s = S[i], e = E[i], l = L[i], r = R[i];
                for (int j = __lg(Root); j >= 0; j--) {
                        if (TR.a[TR.par[j][s]] >= l) s = TR.par[j][s];
                        if (TL.a[TL.par[j][e]] <= r) e = TL.par[j][e];
                }
                ans.emplace_back(tree->Get(TL.tin[e], TL.tout[e], TR.tin[s], TR.tout[s]));
        }

        return ans;
}

Compilation message

werewolf.cpp: In constructor 'tree_t::tree_t(int)':
werewolf.cpp:8:29: warning: 'tree_t::g' will be initialized after [-Wreorder]
    8 |         vector<vector<int>> g, par;
      |                             ^
werewolf.cpp:6:16: warning:   'int tree_t::timer' [-Wreorder]
    6 |         int N, timer;
      |                ^~~~~
werewolf.cpp:10:9: warning:   when initialized here [-Wreorder]
   10 |         tree_t(int N = 0) : N(N), tin(N), tout(N), g(N), timer(0), a(N), par(__lg(N) + 1, vector<int>(N)) {}
      |         ^~~~~~
werewolf.cpp: In constructor 'segtree_t::segtree_t(int, int)':
werewolf.cpp:27:51: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   27 |         segtree_t(int l, int r) : l(l), r(r), m(l + r >> 1), val() {
      |                                                 ~~^~~
werewolf.cpp:25:19: warning: 'segtree_t::m' will be initialized after [-Wreorder]
   25 |         int l, r, m;
      |                   ^
werewolf.cpp:24:21: warning:   'std::vector<int> segtree_t::val' [-Wreorder]
   24 |         vector<int> val;
      |                     ^~~
werewolf.cpp:27:9: warning:   when initialized here [-Wreorder]
   27 |         segtree_t(int l, int r) : l(l), r(r), m(l + r >> 1), val() {
      |         ^~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 344 KB Output is correct
2 Incorrect 0 ms 348 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 344 KB Output is correct
2 Incorrect 0 ms 348 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1668 ms 206936 KB Output is correct
2 Correct 1174 ms 218328 KB Output is correct
3 Correct 1114 ms 216500 KB Output is correct
4 Correct 1314 ms 215480 KB Output is correct
5 Correct 1310 ms 215452 KB Output is correct
6 Correct 1532 ms 215080 KB Output is correct
7 Correct 1377 ms 215616 KB Output is correct
8 Correct 961 ms 218604 KB Output is correct
9 Correct 821 ms 216568 KB Output is correct
10 Incorrect 638 ms 215424 KB Output isn't correct
11 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 344 KB Output is correct
2 Incorrect 0 ms 348 KB Output isn't correct
3 Halted 0 ms 0 KB -