Submission #1197057

#TimeUsernameProblemLanguageResultExecution timeMemory
1197057_callmelucianWerewolf (IOI18_werewolf)C++17
Compilation error
0 ms0 KiB
#include <bits/stdc++.h>
#include "werewolf.h"
using namespace std;

using ll = long long;
using ld = long double;
using pl = pair<ll,ll>;
using pii = pair<int,int>;
using tpl = tuple<int,int,int>;

#define all(a) a.begin(), a.end()
#define filter(a) a.erase(unique(all(a)), a.end())

struct DSU {
    vector<int> lab;
    DSU (int sz) : lab(sz + 1, -1) {}

    int get (int u) {
        if (lab[u] < 0) return u;
        return lab[u] = get(lab[u]);
    }

    int getSz (int u) { return -lab[get(u)]; }

    bool unite (int a, int b) {
        a = get(a), b = get(b);
        if (a == b) return 0;
        if (-lab[a] < -lab[b]) swap(a, b);
        lab[a] += lab[b], lab[b] = a;
        return 1;
    }
};

struct queryItem {
    int st, en, bound, idx;

    queryItem() : st(0), en(0), bound(0), idx(0) {}
    queryItem (int st, int en, int bound, int idx) :
        st(st), en(en), bound(bound), idx(idx) {}
};

const int mn = 6e5 + 5;
int sz[mn], num[mn], chain[mn], depth[mn], par[mn], weight[mn], top[mn], timeDfs;
vector<int> graphAdj[mn], adj[mn];
vector<queryItem> queries[mn];

// custom comparator for set
struct setComp {
    bool operator() (int a, int b) { return num[a] < num[b]; }
};
set<int, setComp> markedNode[mn];

void addEdge (int par, int u) {
    adj[par].push_back(top[u]);
    top[u] = par;
}

int szDfs (int u) {
    sz[u] = 1;
    for (int v : adj[u]) sz[u] += szDfs(v);
    return sz[u];
}

void dfs (int u, int p, int d, bool toP) {
    num[u] = ++timeDfs, par[u] = p, depth[u] = d;
    chain[u] = (toP ? chain[p] : u);
    sort(all(adj[u]), [&] (int a, int b) { return sz[a] > sz[b]; });

    bool heavy = 1;
    for (int v : adj[u])
        dfs(v, u, d + 1, heavy), heavy = 0;
}

int lca (int a, int b) {
    int ap = par[chain[a]], bp = par[chain[b]];
    while (chain[a] != chain[b]) {
        if (depth[ap] == depth[bp]) {
            a = ap, ap = par[chain[a]];
            b = bp, bp = par[chain[b]];
        }
        else if (depth[ap] > depth[bp]) a = ap, ap = par[chain[a]];
        else if (depth[bp] > depth[ap]) b = bp, bp = par[chain[b]];
    }
    return (depth[a] < depth[b] ? a : b);
}

vector<int> check_validity (int N, vector<int> X, vector<int> Y, vector<int> S, vector<int> E, vector<int> L, vector<int> R) {
    /// process input and prepare offline queries
//    int M = sizeof(X) / sizeof(X[0]), Q = sizeof(S) / sizeof(S[0]);
    int M = X.size(), Q = S.size();
    for (int i = 0; i < M; i++) {
        graphAdj[X[i]].push_back(Y[i]);
        graphAdj[Y[i]].push_back(X[i]);
    }
    for (int i = 0; i < Q; i++)
        queries[L[i]].emplace_back(S[i], E[i], R[i], i);

    /// build DSU tree for MST (with Kruskal)
    int node = N - 1; DSU dsu(N);
    for (int i = 0; i < N; i++) {
        bool firstMerge = 1;
        for (int j : graphAdj[i]) {
            if (j > i || !dsu.unite(i, j)) continue;
            if (firstMerge)
                firstMerge = 0, addEdge(++node, i);
            addEdge(node, j);
        }
        if (!firstMerge) weight[node] = i;
        weight[i] = i;
    }

    /// process DSU tree
    szDfs(node), dfs(node, 0, 1, 0);

    /// build MST (max) and process queries
    vector<int> res(Q);
    dsu = DSU(N);
    for (int i = 0; i < N; i++) markedNode[i].insert(i);
    for (int i = N - 1; i >= 0; i--) {
        for (int j : graphAdj[i]) {
            int u = dsu.get(i), v = dsu.get(j);
            if (j > i && dsu.unite(i, j)) {
                if (u == dsu.get(i)) swap(u, v);
                for (int iter : markedNode[u])
                    markedNode[v].insert(iter);
                markedNode[u].clear();
            }
        }
        for (queryItem &iter : queries[i]) {
            int root = dsu.get(iter.st), opt = INT_MAX;
            auto it = markedNode[root].lower_bound(iter.en);
            if (it != markedNode[root].end()) {
                int lc = lca(iter.en, *it);
                opt = min(opt, weight[lc]);
            }
            if (it != markedNode[root].begin()) {
                int lc = lca(iter.en, *prev(it));
                opt = min(opt, weight[lc]);
            }
            res[iter.idx] = (opt <= iter.bound);
//            cout << "query " << iter.idx << " " << opt << " " << iter.bound << endl;
//            for (int u : markedNode[root]) cout << u << " ";
//            cout << endl;
        }
    }
    return res;
}

#ifdef LOCAL
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    vector<int> X = {5, 1, 1, 3, 3, 5};
    vector<int> Y = {1, 2, 3, 4, 0, 2};
    vector<int> S = {4, 4, 5};
    vector<int> E = {2, 2, 4};
    vector<int> L = {1, 2, 3};
    vector<int> R = {2, 2, 4};

//    cout << sizeof(X) << " ";

    vector<int> res = check_validity(6, X, Y, S, E, L, R);
    for (int u : res) cout << u << " ";

    return 0;
}
#endif LOCAL

Compilation message (stderr)

werewolf.cpp:169:8: warning: extra tokens at end of #endif directive [-Wendif-labels]
  169 | #endif LOCAL
      |        ^~~~~
In file included from /usr/include/c++/11/map:60,
                 from /usr/include/x86_64-linux-gnu/c++/11/bits/stdc++.h:81,
                 from werewolf.cpp:1:
/usr/include/c++/11/bits/stl_tree.h: In instantiation of 'static const _Key& std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_S_key(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type) [with _Key = int; _Val = int; _KeyOfValue = std::_Identity<int>; _Compare = setComp; _Alloc = std::allocator<int>; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type = const std::_Rb_tree_node<int>*]':
/usr/include/c++/11/bits/stl_tree.h:2071:47:   required from 'std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_unique_pos(const key_type&) [with _Key = int; _Val = int; _KeyOfValue = std::_Identity<int>; _Compare = setComp; _Alloc = std::allocator<int>; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = int]'
/usr/include/c++/11/bits/stl_tree.h:2124:4:   required from 'std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = const int&; _Key = int; _Val = int; _KeyOfValue = std::_Identity<int>; _Compare = setComp; _Alloc = std::allocator<int>]'
/usr/include/c++/11/bits/stl_set.h:512:25:   required from 'std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Tp>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const value_type&) [with _Key = int; _Compare = setComp; _Alloc = std::allocator<int>; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Tp>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator = std::_Rb_tree<int, int, std::_Identity<int>, setComp, std::allocator<int> >::const_iterator; typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other = std::allocator<int>; typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key> = __gnu_cxx::__alloc_traits<std::allocator<int>, int>::rebind<int>; typename _Alloc::value_type = int; std::set<_Key, _Compare, _Alloc>::value_type = int]'
werewolf.cpp:118:53:   required from here
/usr/include/c++/11/bits/stl_tree.h:770:15: error: static assertion failed: comparison object must be invocable as const
  770 |               is_invocable_v<const _Compare&, const _Key&, const _Key&>,
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/11/bits/stl_tree.h:770:15: note: 'std::is_invocable_v<const setComp&, const int&, const int&>' evaluates to false