Submission #1350894

#TimeUsernameProblemLanguageResultExecution timeMemory
1350894nguyenbaoanhWerewolf (IOI18_werewolf)C++20
Compilation error
0 ms0 KiB
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 500005;

int n, m, q;
vector<pair<int,int>> edges;

// KRT
vector<int> adj1[MAXN * 2], adj2[MAXN * 2];
int par1[20][MAXN * 2], par2[20][MAXN * 2];
int mn1[MAXN * 2], mx1[MAXN * 2];
int mn2[MAXN * 2], mx2[MAXN * 2];

int fu1[MAXN * 2], fu2[MAXN * 2];

// Euler
int in1[MAXN * 2], out1[MAXN * 2], timer1;
int in2[MAXN * 2], out2[MAXN * 2], timer2;

// BIT
int bit[MAXN];

void upd(int i, int v) {
    for (; i <= n; i += i & -i) bit[i] += v;
}
int get(int i) {
    int s = 0;
    for (; i > 0; i -= i & -i) s += bit[i];
    return s;
}
int query(int l, int r) {
    return get(r) - get(l - 1);
}

// DSU find
int find(int *fu, int x) {
    return fu[x] < 0 ? x : fu[x] = find(fu, fu[x]);
}

// build KRT
int buildKRT(vector<pair<int,int>> ed, vector<int> adj[], int *fu, int *mn, int *mx) {
    int tot = n;
    for (int i = 1; i <= 2*n; i++) fu[i] = -1;

    for (auto [u, v] : ed) {
        int x = find(fu, u);
        int y = find(fu, v);
        if (x == y) continue;

        ++tot;
        adj[tot].push_back(x);
        adj[tot].push_back(y);

        fu[x] = fu[y] = tot;
        fu[tot] = -1;
    }

    return tot;
}

// DFS build in/out + mn/mx
void dfs1(int u) {
    in1[u] = ++timer1;
    if (u <= n) mn1[u] = mx1[u] = u;
    else {
        mn1[u] = 1e9;
        mx1[u] = -1;
        for (int v : adj1[u]) {
            dfs1(v);
            mn1[u] = min(mn1[u], mn1[v]);
            mx1[u] = max(mx1[u], mx1[v]);
        }
    }
    out1[u] = timer1;
}

void dfs2(int u) {
    in2[u] = ++timer2;
    if (u <= n) mn2[u] = mx2[u] = u;
    else {
        mn2[u] = 1e9;
        mx2[u] = -1;
        for (int v : adj2[u]) {
            dfs2(v);
            mn2[u] = min(mn2[u], mn2[v]);
            mx2[u] = max(mx2[u], mx2[v]);
        }
    }
    out2[u] = timer2;
}

// jump
int jump1(int u, int L) {
    for (int k = 19; k >= 0; k--) {
        int p = par1[k][u];
        if (p && mn1[p] >= L) u = p;
    }
    return u;
}

int jump2(int u, int R) {
    for (int k = 19; k >= 0; k--) {
        int p = par2[k][u];
        if (p && mx2[p] <= R) u = p;
    }
    return u;
}

struct Query {
    int l1, r1, l2, r2, id, sign;
};

vector<Query> qs[MAXN];
int ans[MAXN];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> m >> q;
    edges.resize(m);

    for (auto &e : edges) cin >> e.first >> e.second;

    // build KRT1 (>= L)
    auto e1 = edges;
    for (auto &e : e1) if (e.first > e.second) swap(e.first, e.second);
    sort(e1.begin(), e1.end(), [](auto a, auto b){
        return max(a.first,a.second) > max(b.first,b.second);
    });

    int root1 = buildKRT(e1, adj1, fu1, mn1, mx1);

    // build KRT2 (<= R)
    auto e2 = edges;
    for (auto &e : e2) if (e.first < e.second) swap(e.first, e.second);
    sort(e2.begin(), e2.end(), [](auto a, auto b){
        return min(a.first,a.second) < min(b.first,b.second);
    });

    int root2 = buildKRT(e2, adj2, fu2, mn2, mx2);

    // dfs
    dfs1(root1);
    dfs2(root2);

    // build binary lifting
    for (int i = 1; i <= root1; i++)
        for (int v : adj1[i])
            par1[0][v] = i;

    for (int k = 1; k < 20; k++)
        for (int i = 1; i <= root1; i++)
            par1[k][i] = par1[k-1][par1[k-1][i]];

    for (int i = 1; i <= root2; i++)
        for (int v : adj2[i])
            par2[0][v] = i;

    for (int k = 1; k < 20; k++)
        for (int i = 1; i <= root2; i++)
            par2[k][i] = par2[k-1][par2[k-1][i]];

    // queries
    for (int i = 1; i <= q; i++) {
        int S, E, L, R;
        cin >> S >> E >> L >> R;

        int u = jump1(S, L);
        int v = jump2(E, R);

        int l1 = in1[u], r1 = out1[u];
        int l2 = in2[v], r2 = out2[v];

        qs[r1].push_back({l1, r1, l2, r2, i, +1});
        qs[l1-1].push_back({l1, r1, l2, r2, i, -1});
    }

    // build pos in B
    vector<int> A(n+1), B(n+1), posB(n+1);

    for (int i = 1; i <= n; i++) {
        A[in1[i]] = i;
        B[in2[i]] = i;
    }
    for (int i = 1; i <= n; i++) {
        posB[B[i]] = i;
    }

    // sweep
    for (int i = 1; i <= n; i++) {
        int v = A[i];
        int pos = posB[v];
        upd(pos, 1);

        for (auto qu : qs[i]) {
            int val = query(qu.l2, qu.r2);
            ans[qu.id] += qu.sign * val;
        }
    }

    for (int i = 1; i <= q; i++) {
        cout << (ans[i] > 0) << '\n';
    }
}

Compilation message (stderr)

/usr/bin/ld: /tmp/ccMUgX3m.o: in function `main':
grader.cpp:(.text.startup+0x0): multiple definition of `main'; /tmp/ccLbptKh.o:werewolf.cpp:(.text.startup+0x0): first defined here
/usr/bin/ld: /tmp/ccMUgX3m.o: in function `main':
grader.cpp:(.text.startup+0x3ab): undefined reference to `check_validity(int, std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >)'
collect2: error: ld returned 1 exit status