QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#448568#8809. Telephone PlansQwerty12320 0ms3792kbC++236.0kb2024-06-19 19:46:002024-06-19 19:46:01

Judging History

你现在查看的是最新测评结果

  • [2024-06-19 19:46:01]
  • 评测
  • 测评结果:0
  • 用时:0ms
  • 内存:3792kb
  • [2024-06-19 19:46:00]
  • 提交

answer

#include <iostream>
// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
#include <bits/stdc++.h>

std::mt19937 rnd;

using u32 = uint32_t;

struct Node {
    Node *left, *right;
    Node* prev;
    u32 y;
    int sz;

    // int u, v;
    // std::pair<int, int> edge;

    Node(std::pair<int, int> e) : y(rnd()), left(nullptr), right(nullptr), prev(nullptr), sz(1)
    // , u(e.first), v(e.second)
    { sizeof(Node); }
};

int get_sz(Node* p) {
    return p ? p->sz : 0;
}
void upd_prv(Node* p, Node* prv) {
    if (p) {
        p->prev = prv;
    }
}

void upd(Node* p) {
    if (p) {
        upd_prv(p->left, p);
        upd_prv(p->right, p);
        p->sz = 1 + get_sz(p->left) + get_sz(p->right);
    }
}

Node* merge(Node* a, Node* b) {
    if (!a || !b) {
        return a ? a : b;
    }
    if (a->y < b->y) {
        a->right = merge(a->right, b);
        return upd(a), a;
    } else {
        b->left = merge(a, b->left);
        return upd(b), b;
    }
}

Node* merge(std::initializer_list<Node*> list) {
    Node* rt = nullptr;
    for (Node* ptr : list) {
        rt = merge(rt, ptr);
    }
    return rt;
}

std::pair<Node*, Node*> split(Node* p, int ind) {
    if (!p) {
        return {nullptr, nullptr};
    }
    if (get_sz(p->left) + 1 <= ind) {
        auto [a, b] = split(((p->right ? p->right->prev = nullptr : 0), p->right), ind - (get_sz(p->left) + 1));
        p->right = a;
        upd(p);
        return {p, b};
    } else {
        auto [a, b] = split(((p->left ? p->left->prev = nullptr : 0), p->left), ind);
        p->left = b;
        upd(p);
        return {a, p};
    }
}

template <int N>
std::array<Node*, N> split(Node* p, std::array<int, N - 1> ar) {
    std::array<Node*, N> res;
    for (int i = 0; i < N - 1; i++) {
        auto [a, b] = split(p, ar[i] - (i == 0 ? 0 : ar[i - 1]));
        res[i] = a;
        res[i + 1] = b;
        p = b;
    }
    return res;
}

std::pair<Node*, int> ascend(Node* p) {
    // assert(p);
    if (!p) {
        return {p, 0};
    }
    int ind = get_sz(p->left);
    while (p->prev) {
        ind += (get_sz(p->prev->left) + 1) * (p == p->prev->right);
        p = p->prev;
    }
    return {p, ind};
}

void print(Node* ptr) {
    if (!ptr) {
        return;
    }
    print(ptr->left);
    // std::cerr << " " << ptr->u << "->" << ptr->v << ", ";
    print(ptr->right);
}

int32_t main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int E;
    int n, q;
    std::cin >> E >> n >> q;

    int64_t all_dlt = 0;
    std::vector<int64_t> ans = {0};
    std::vector<std::vector<int>> gr(n);

    int64_t cur_sum = 0;
    int64_t last_ans = 0;

    std::map<std::pair<int, int>, std::pair<Node*, Node*>> map;
    std::vector<std::unordered_set<Node*>> cum(n);  // out edge

    for (int i = 0; i < q; i++) {
        int tp;
        std::cin >> tp;
        if (tp == 3) {
            int64_t t;
            std::cin >> t;
            if (E == 1) {
                t ^= last_ans;
            }

            ans.push_back(ans.back());
            last_ans = ans.rbegin()[t] + all_dlt;
            std::cout << ans.rbegin()[t] + all_dlt << "\n";
        } else {
            int64_t u, v;

            assert(v < 1e10);
            assert(u < 1e10);

            std::cin >> u >> v;
            if (E == 1) {
                u ^= last_ans;
                v ^= last_ans;
            }
            u--;
            v--;

            if (u > v) {
                std::swap(u, v);
            }

            if (tp == 1) {
                Node *rt1 = cum[u].size() ? cum[u].begin().operator*() : nullptr,
                     *rt2 = cum[v].size() ? cum[v].begin().operator*() : nullptr;
                Node *uv = new Node({u, v}), *vu = new Node({v, u});
                map[{u, v}] = {uv, vu};

                auto [r1, ind1] = ascend(rt1);
                auto [r2, ind2] = ascend(rt2);

                // print(r1);
                // std::cerr << "\n";
                // print(r2);
                // std::cerr << "\n";

                int sz1 = get_sz(r1) / 2 + 1;
                int sz2 = get_sz(r2) / 2 + 1;

                auto [x1, y1] = split(r1, ind1);
                auto [x2, y2] = split(r2, ind2);

                auto rt = merge({x1, uv, y2, x2, vu, y1});

                cum[u].insert(uv);
                cum[v].insert(vu);

                int64_t dlt = int64_t(sz1) * sz2;
                ans.push_back(ans.back());
                cur_sum += dlt;

                // for (auto& val : ans) {
                //     val += dlt;
                // }
                all_dlt += dlt;
                // print(rt);
                // std::cerr << "\n";
            } else {
                auto [uv, vu] = map[{u, v}];
                map.erase({u, v});

                auto [rt, ind1] = ascend(uv);
                auto [__, ind2] = ascend(vu);

                bool swp = false;
                if (ind1 > ind2) {
                    std::swap(ind1, ind2);
                    swp = true;
                }

                auto [a, b, c, d, e] = split<5>(rt, {ind1, ind1 + 1, ind2, ind2 + 1});
                cum[u].erase(b);
                cum[u].erase(d);
                cum[v].erase(b);
                cum[v].erase(d);
                assert(b->prev == nullptr && b->sz == 1);
                assert(d->prev == nullptr && d->sz == 1);
                delete b, d;

                auto f = merge(a, e);

                int sz1 = get_sz(f) / 2 + 1;
                int sz2 = get_sz(c) / 2 + 1;

                // std::erase(gr[u], v);
                // std::erase(gr[v], u);

                // int sz1 = dfs(dfs, u, -1);
                // int sz2 = dfs(dfs, v, -1);
                int64_t dlt = int64_t(sz1) * sz2;
                cur_sum -= dlt;
                ans.push_back({cur_sum - all_dlt});
            }
        }
    }

    return 0;
}

詳細信息

Subtask #1:

score: 0
Runtime Error

Test #1:

score: 3
Accepted
time: 0ms
memory: 3792kb

input:

0
1 147
3 0
3 0
3 1
3 1
3 0
3 5
3 5
3 1
3 1
3 4
3 8
3 2
3 10
3 13
3 10
3 8
3 8
3 0
3 16
3 3
3 1
3 20
3 2
3 10
3 16
3 13
3 17
3 12
3 22
3 7
3 8
3 2
3 12
3 32
3 12
3 31
3 2
3 0
3 21
3 24
3 28
3 32
3 9
3 18
3 26
3 11
3 45
3 35
3 14
3 34
3 49
3 31
3 43
3 11
3 21
3 50
3 4
3 11
3 31
3 51
3 28
3 26
3 18
3 ...

output:

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

result:

ok 147 lines

Test #2:

score: -3
Runtime Error

input:

0
2 10
1 1 2
3 1
3 1
3 2
3 3
3 3
3 3
2 1 2
3 2
3 3

output:


result:


Subtask #2:

score: 0
Runtime Error

Test #29:

score: 2
Accepted
time: 0ms
memory: 3556kb

input:

1
1 147
3 0
3 0
3 1
3 1
3 3
3 0
3 6
3 6
3 0
3 2
3 0
3 5
3 12
3 1
3 2
3 10
3 13
3 15
3 3
3 12
3 20
3 18
3 10
3 12
3 2
3 12
3 14
3 26
3 12
3 24
3 7
3 7
3 6
3 29
3 32
3 16
3 23
3 14
3 25
3 13
3 13
3 31
3 20
3 26
3 0
3 40
3 23
3 28
3 35
3 1
3 31
3 2
3 34
3 37
3 3
3 39
3 17
3 4
3 41
3 11
3 16
3 48
3 10
3...

output:

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

result:

ok 147 lines

Test #30:

score: -2
Runtime Error

input:

1
2 10
1 1 2
3 1
3 1
3 1
3 1
3 1
3 2
3 6
2 0 3
3 2

output:


result:


Subtask #3:

score: 0
Skipped

Dependency #1:

0%

Subtask #4:

score: 0
Skipped

Dependency #2:

0%

Subtask #5:

score: 0
Skipped

Dependency #3:

0%

Subtask #6:

score: 0
Skipped

Dependency #4:

0%

Subtask #7:

score: 0
Skipped

Dependency #6:

0%