답안 #589904

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
589904 2022-07-05T11:37:23 Z nguyen31hoang08minh2003 Klasika (COCI20_klasika) C++14
0 / 110
1044 ms 524288 KB
/*
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|
|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|
|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|
|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|
|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|-\/\/-|
|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|\/\/\/|
|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|/-/\-\|
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|\-\/-/|
|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|/\/\/\|
|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|-/\/\-|
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
*/
#include <bits/stdc++.h>
#define fore(i, a, b) for (signed i = (a), i##_last = (b); i < i##_last; ++i)
#define fort(i, a, b) for (signed i = (a), i##_last = (b); i <= i##_last; ++i)
#define ford(i, a, b) for (signed i = (a), i##_last = (b); i >= i##_last; --i)
#define fi first
#define se second
#define pb push_back
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define subtree(x) num[x], num[x] + d[x] - 1
using namespace std;
using ll = long long;
using ld = long double;

template<class A, class B> bool maxi(A &a, const B &b) {return (a < b) ? (a = b, true):false;};
template<class A, class B> bool mini(A &a, const B &b) {return (a > b) ? (a = b, true):false;};

typedef unsigned long long ull;
typedef pair<int, int> ii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef vector<vii> vvii;

class BinaryTrie {
private:
    int length, depth;
    vector<array<int, 2> > trie;
public:
    BinaryTrie(const int depth): trie(1, {-1, -1}), length(0), depth(depth) {};
    void append(const int mask) {
        int x = 0, y;
        ford(i, depth, 0) {
            y = ((mask >> i) & 1);
            if (trie[x][y] < 0) {
                trie[x][y] = ++length;
                trie.push_back({-1, -1});
            }
            x = trie[x][y];
        }
    }
    int query(const int mask) const {
        int res = 0, x = 0, y;
        ford(i, depth, 0) {
            y = ((mask >> i) & 1) ^ 1;
            if (trie[x][y] < 0) {
                if (y ^ 1)
                    res |= 1 << i;
                x = trie[x][y ^ 1];
            } else {
                if (y)
                    res |= 1 << i;
                x = trie[x][y];
            }
        }
        return res;
    }
};

class Trie {
private:
    int length, depth;
    vector<array<int, 2> > trie;
public:
    Trie(const int depth): trie(1, {-1, -1}), length(0), depth(depth) {};
    void append(const int mask) {
        int x = 0, y;
        ford(i, depth, 0) {
            y = ((mask >> i) & 1);
            if (trie[x][y] < 0) {
                trie[x][y] = ++length;
                trie.push_back({-1, -1});
            }
            x = trie[x][y];
        }
    }
    int query(const int mask) const {
        int res = 0, x = 0, y;
        ford(i, depth, 0) {
            y = ((mask >> i) & 1) ^ 1;
            if (trie[x][y] < 0) {
                x = trie[x][y ^ 1];
            } else {
                res |= 1 << i;
                x = trie[x][y];
            }
        }
        return res;
    }
};

class SegmentTree {
private:
    int n;
    vector<Trie> it;

    void update(const int q, const int mask, const int i, const int l, const int r) {
        if (q < l || r < q)
            return;
        it[i].append(mask);
        if (l == r)
            return;
        const int m = l + r >> 1;
        update(q, mask, i << 1, l, m);
        update(q, mask, i << 1 | 1, m + 1, r);
    }

    int query(const int ql, const int qr, const int mask, const int i, const int l, const int r) const {
        if (qr < l || r < ql)
            return 0;
        if (ql <= l && r <= qr)
            return it[i].query(mask);
        const int m = l + r >> 1;
        return max(query(ql, qr, mask, i << 1, l, m), query(ql, qr, mask, i << 1 | 1, m + 1, r));
    };

public:
    SegmentTree(): n(0) {};
    SegmentTree(const int n): n(n), it(n + 5 << 2, Trie(30)) {};

    void update(const int q, const int mask) {
        update(q, mask, 1, 1, n);
    }

    void resize(int newSize) {
        n = newSize;
        newSize = n + 5 << 2;
        it.resize(newSize, Trie(30));
    }

    int query(const int ql, const int qr, const int mask) const {
        return query(ql, qr, mask, 1, 1, n);
    }
};

int q;

void subtask2() {
    vi h(2);
    vii p(2);
    string t;
    vvii adj(2);
    int x, y, a, b, n = 1, res, g;
    const function<int(int, int)> findDistance = [&](int x, int y) -> int {
        int res = 0;
        for (; h[x] > h[y]; x = p[x].se)
            res ^= p[x].fi;
        for (; h[y] > h[x]; y = p[y].se)
            res ^= p[y].fi;
        while (x != y) {
            res ^= p[x].fi ^ p[y].fi;
            x = p[x].se;
            y = p[y].se;
        }
        return res;
    };
    const function<void(int, int)> dfs = [&res, &adj, &g, &dfs](const int u, const int d) {
        maxi(res, g ^ d);
        for (const auto &[w, v] : adj[u])
            dfs(v, d ^ w);
    };
    fort(_, 1, q) {
        cin >> t;
        if (t == "Add") {
            cin >> x >> y;
            adj.pb(vii());
            adj[x].emplace_back(y, ++n);
            h.pb(h[x] + 1);
            p.emplace_back(y, x);
        } else {
            cin >> a >> b;
            res = g = findDistance(a, b);
            dfs(b, 0);
            cout << res << '\n';
        }
    }
}

void subtask3() {
    vi h(2);
    string t;
    int x, y, a, b;
    BinaryTrie trie(30);
    trie.append(0);
    fort(_, 1, q) {
        cin >> t;
        if (t == "Add") {
            cin >> x >> y;
            h.pb(h[x] ^ y);
            trie.append(h.back());
        } else {
            cin >> a >> b;
            cout << (h[a] ^ trie.query(h[a])) << '\n';
        }
    }
}

void subtask4() {
    vvii adj(2);
    SegmentTree it;
    vi h(2), num, d;
    int n = 1, t = 0;
    vector<tuple<string, int, int> > queries(q);
    const function<void(int)> dfs = [&adj, &t, &num, &d, &dfs](const int u) {
        num[u] = ++t;
        ++d[u];
        for (const auto &[w, v] : adj[u]) {
            dfs(v);
            d[u] += d[v];
        }
    };
//-----------------------------------Create graph------------------------------------------
    for (auto &[z, x, y] : queries) {
        cin >> z >> x >> y;
        if (z == "Add") {
            adj.pb(vii());
            adj[x].emplace_back(y, ++n);
            h.pb(h[x] ^ y);
        }
    }
//-----------------------------------Numbering----------------------------------------------
    num.resize(n + 1);
    d.resize(n + 1);
    it.resize(n);
    dfs(1);
    it.update(num[1], 0);
//-----------------------------------Calculate answers---------------------------------------
    t = 1;
    for (const auto &[z, x, y] : queries) {
        if (z == "Add") {
            ++t;
            it.update(num[t], h[t]);
            continue;
        }
        cout << it.query(subtree(y), h[x]) << '\n';
    }
}

int main() {
    #ifdef LOCAL
        freopen("input.INP", "r", stdin);
    #endif // LOCAL
    cin.tie(0) -> sync_with_stdio(0);
    cout.tie(0);
    cin >> q;
    subtask4();
    return 0;
}

Compilation message

klasika.cpp: In constructor 'BinaryTrie::BinaryTrie(int)':
klasika.cpp:48:28: warning: 'BinaryTrie::trie' will be initialized after [-Wreorder]
   48 |     vector<array<int, 2> > trie;
      |                            ^~~~
klasika.cpp:47:9: warning:   'int BinaryTrie::length' [-Wreorder]
   47 |     int length, depth;
      |         ^~~~~~
klasika.cpp:50:5: warning:   when initialized here [-Wreorder]
   50 |     BinaryTrie(const int depth): trie(1, {-1, -1}), length(0), depth(depth) {};
      |     ^~~~~~~~~~
klasika.cpp: In constructor 'Trie::Trie(int)':
klasika.cpp:83:28: warning: 'Trie::trie' will be initialized after [-Wreorder]
   83 |     vector<array<int, 2> > trie;
      |                            ^~~~
klasika.cpp:82:9: warning:   'int Trie::length' [-Wreorder]
   82 |     int length, depth;
      |         ^~~~~~
klasika.cpp:85:5: warning:   when initialized here [-Wreorder]
   85 |     Trie(const int depth): trie(1, {-1, -1}), length(0), depth(depth) {};
      |     ^~~~
klasika.cpp: In member function 'void SegmentTree::update(int, int, int, int, int)':
klasika.cpp:123:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  123 |         const int m = l + r >> 1;
      |                       ~~^~~
klasika.cpp: In member function 'int SegmentTree::query(int, int, int, int, int, int) const':
klasika.cpp:133:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  133 |         const int m = l + r >> 1;
      |                       ~~^~~
klasika.cpp: In constructor 'SegmentTree::SegmentTree(int)':
klasika.cpp:139:42: warning: suggest parentheses around '+' inside '<<' [-Wparentheses]
  139 |     SegmentTree(const int n): n(n), it(n + 5 << 2, Trie(30)) {};
      |                                        ~~^~~
klasika.cpp: In member function 'void SegmentTree::resize(int)':
klasika.cpp:147:21: warning: suggest parentheses around '+' inside '<<' [-Wparentheses]
  147 |         newSize = n + 5 << 2;
      |                   ~~^~~
klasika.cpp: In lambda function:
klasika.cpp:179:26: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  179 |         for (const auto &[w, v] : adj[u])
      |                          ^
klasika.cpp: In lambda function:
klasika.cpp:227:26: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  227 |         for (const auto &[w, v] : adj[u]) {
      |                          ^
klasika.cpp: In function 'void subtask4()':
klasika.cpp:233:16: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  233 |     for (auto &[z, x, y] : queries) {
      |                ^
klasika.cpp:249:22: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  249 |     for (const auto &[z, x, y] : queries) {
      |                      ^
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1 ms 468 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1 ms 468 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 387 ms 171860 KB Output is correct
2 Correct 683 ms 345032 KB Output is correct
3 Correct 1044 ms 515056 KB Output is correct
4 Runtime error 990 ms 524288 KB Execution killed with signal 9
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1 ms 468 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -