답안 #809026

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
809026 2023-08-05T14:20:33 Z math_rabbit_1028 늑대인간 (IOI18_werewolf) C++14
15 / 100
487 ms 287344 KB
#include "werewolf.h"
#include <bits/stdc++.h>
using namespace std;
int n, m, q;
vector<int> adj[202020];

struct disjoint {
    int root[202020], num[202020];
    int r, mn[404040], mx[404040], par[404040];
    vector<int> child[404040];
    int _find(int v) {
        if (v == root[v]) return v;
        else return root[v] = _find(root[v]);
    }
    void _union(int v, int u) {
        v = _find(v);
        u = _find(u);
        if (v == u) return;
        if (v > u) swap(u, v);
        root[u] = v;
        child[r].push_back(num[v]);
        child[r].push_back(num[u]);
        par[num[v]] = par[num[u]] = r;
        mn[r] = min(mn[num[v]], mn[num[u]]);
        mx[r] = max(mx[num[v]], mx[num[u]]);
        num[v] = r;
        r++;
    }

    int ord[808080], lt[404040], rt[404040], s;
    void ett() {
        s = 0;
        DFS(r - 1);
    }
    void DFS(int v) {
        ord[++s] = v;
        lt[v] = s;
        for (int i = 0; i < child[v].size(); i++) {
            int next = child[v][i];
            DFS(next);
            ord[++s] = v;
        }
        rt[v] = s;
    }

    int table[404040][20];
    void sparse() {
        for (int i = 0; i < r; i++) table[i][0] = par[i];
        for (int k = 1; k < 20; k++) {
            for (int i = 0; i < r; i++) {
                if (table[i][k - 1] < 0) table[i][k] = -1;
                else table[i][k] = table[table[i][k - 1]][k - 1];
            }
        }
        /*
        for (int i = 0; i < r; i++) {
            for (int k = 0; k < 20; k++) cout << table[i][k] << " ";
            cout << "\n";
        }
        cout << "\n";
        */
    }

    pair<int, int> get_segment(int st, int limit, int f) {
        if (f) {
            int now = st;
            for (int k = 19; k >= 0; k--) {
                if (table[now][k] != -1 && mn[table[now][k]] >= limit) now = table[now][k];
            }
            return {lt[now], rt[now]};
        }
        else {
            int now = st;
            for (int k = 19; k >= 0; k--) {
                if (table[now][k] != -1 && mx[table[now][k]] <= limit) now = table[now][k];
            }
            return {lt[now], rt[now]};
        }
    }
} left_tree, right_tree;

void make_left_tree() {
    for (int i = 0; i < n; i++) left_tree.root[i] = i;
    for (int i = 0; i < n; i++) left_tree.num[i] = i;
    for (int i = 0; i < n; i++) left_tree.mn[i] = left_tree.mx[i] = i;
    left_tree.r = n;

    for (int i = n - 1; i >= 0; i--) {
        for (int j = 0; j < adj[i].size(); j++) {
            int v = adj[i][j];
            if (v >= i) left_tree._union(i, v);
        }
    }
    left_tree.par[left_tree.r - 1] = -1;
}
void make_right_tree() {
    for (int i = 0; i < n; i++) right_tree.root[i] = i;
    for (int i = 0; i < n; i++) right_tree.num[i] = i;
    for (int i = 0; i < n; i++) right_tree.mn[i] = right_tree.mx[i] = i;
    right_tree.r = n;

    for (int i = 0; i <= n - 1; i++) {
        for (int j = 0; j < adj[i].size(); j++) {
            int v = adj[i][j];
            if (v <= i) right_tree._union(i, v);
        }
    }
    right_tree.par[right_tree.r - 1] = -1;
}

vector<int> ans;
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) {
    n = N; m = X.size();
    for (int i = 0; i < m; i++) {
        adj[X[i]].push_back(Y[i]);
        adj[Y[i]].push_back(X[i]);
    }

    make_left_tree();
    left_tree.ett();
    left_tree.sparse();

    make_right_tree();
    right_tree.ett();
    right_tree.sparse();

    q = S.size();
    for (int i = 0; i < q; i++) ans.push_back(0);
    for (int i = 0; i < q; i++) {
        int s = S[i], e = E[i], l = L[i], r = R[i];
        pair<int, int> left_segment = left_tree.get_segment(s, l, 1);
        //cout << left_segment.first << " " << left_segment.second << "\n";
        pair<int, int> right_segment = right_tree.get_segment(e, r, 0);
        //cout << right_segment.first << " " << right_segment.second << "\n";
        int ch[3030];
        for (int j = 0; j < n; j++) ch[j] = 0;
        for (int j = left_segment.first; j <= left_segment.second; j++)
            if (left_tree.ord[j] < n) ch[left_tree.ord[j]] = 1;
        for (int j = right_segment.first; j <= right_segment.second; j++)
            if (right_tree.ord[j] < n && ch[right_tree.ord[j]] == 1) ans[i] = 1;
    }

    return ans;
}

Compilation message

werewolf.cpp: In member function 'void disjoint::DFS(int)':
werewolf.cpp:38:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   38 |         for (int i = 0; i < child[v].size(); i++) {
      |                         ~~^~~~~~~~~~~~~~~~~
werewolf.cpp: In function 'void make_left_tree()':
werewolf.cpp:89:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   89 |         for (int j = 0; j < adj[i].size(); j++) {
      |                         ~~^~~~~~~~~~~~~~~
werewolf.cpp: In function 'void make_right_tree()':
werewolf.cpp:103:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  103 |         for (int j = 0; j < adj[i].size(); j++) {
      |                         ~~^~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 12 ms 24168 KB Output is correct
2 Correct 11 ms 24148 KB Output is correct
3 Correct 10 ms 24172 KB Output is correct
4 Correct 10 ms 24040 KB Output is correct
5 Correct 10 ms 24172 KB Output is correct
6 Correct 15 ms 24148 KB Output is correct
7 Correct 11 ms 24168 KB Output is correct
8 Correct 14 ms 24168 KB Output is correct
9 Correct 10 ms 24176 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 12 ms 24168 KB Output is correct
2 Correct 11 ms 24148 KB Output is correct
3 Correct 10 ms 24172 KB Output is correct
4 Correct 10 ms 24040 KB Output is correct
5 Correct 10 ms 24172 KB Output is correct
6 Correct 15 ms 24148 KB Output is correct
7 Correct 11 ms 24168 KB Output is correct
8 Correct 14 ms 24168 KB Output is correct
9 Correct 10 ms 24176 KB Output is correct
10 Correct 92 ms 26068 KB Output is correct
11 Correct 76 ms 26156 KB Output is correct
12 Correct 24 ms 25956 KB Output is correct
13 Correct 70 ms 26104 KB Output is correct
14 Correct 61 ms 26104 KB Output is correct
15 Correct 50 ms 26068 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Runtime error 487 ms 287344 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 12 ms 24168 KB Output is correct
2 Correct 11 ms 24148 KB Output is correct
3 Correct 10 ms 24172 KB Output is correct
4 Correct 10 ms 24040 KB Output is correct
5 Correct 10 ms 24172 KB Output is correct
6 Correct 15 ms 24148 KB Output is correct
7 Correct 11 ms 24168 KB Output is correct
8 Correct 14 ms 24168 KB Output is correct
9 Correct 10 ms 24176 KB Output is correct
10 Correct 92 ms 26068 KB Output is correct
11 Correct 76 ms 26156 KB Output is correct
12 Correct 24 ms 25956 KB Output is correct
13 Correct 70 ms 26104 KB Output is correct
14 Correct 61 ms 26104 KB Output is correct
15 Correct 50 ms 26068 KB Output is correct
16 Runtime error 487 ms 287344 KB Execution killed with signal 11
17 Halted 0 ms 0 KB -