Cod sursa(job #2746998)

Utilizator Maria23Dutu Maria Maria23 Data 28 aprilie 2021 19:11:09
Problema Heapuri cu reuniune Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.16 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream cin ("mergeheap.in");
ofstream cout ("mergeheap.out");

const int MAX = 300000;

struct node {
    int value;
    int subTree;
}information[MAX];

int createNode(const int value) {
    static int label = 0;
    ++ label;
    information[label].value = value;
    information[label].subTree = 1;
    return label;
}

const int NMAX = 100;

vector <int> sets[NMAX];
int bestMax[NMAX];
vector <int> graph[MAX];


int main() {
    vector <int> logs(MAX + 10);
    logs[0] = 0;
    for (int i = 1; i <= MAX; ++ i) {
        logs[i] = logs[i >> 1] + 1;
    }

    int n, q;
    cin >> n >> q;
    while (q --) {
        int tip;
        cin >> tip;
        if (tip == 1) {
            int m, value;
            cin >> m >> value;
            auto whichNode = createNode(value);
            sets[m].push_back(whichNode);
            if (sets[m].size() == 1) {
                bestMax[m] = value;
            }
            else {
                bestMax[m] = max(bestMax[m], value);
            }
        }
        else if (tip == 2) {
            int m;
            cin >> m;
            cout << bestMax[m] << '\n';
            for (int ind = 0; ind < (int)sets[m].size(); ++ ind) {
                auto whichNode = sets[m][ind];
                if (information[whichNode].value == bestMax[m]) {
                    swap(sets[m][ind], sets[m][(int)sets[m].size() - 1]);
                    break;
                }
            }
            auto whichNode = sets[m].back();
            sets[m].pop_back();
            vector <int> degs(logs[information[whichNode].subTree] + 1, -1);
            for (auto child: graph[whichNode]) {
                auto currentNode = child;
                auto curDeg = graph[currentNode].size();
                while (degs[curDeg] != -1) {
                    auto counterPart = degs[curDeg];
                    if (information[currentNode].value < information[counterPart].value) {
                        swap(currentNode, counterPart);
                    }
                    information[currentNode].subTree += information[counterPart].subTree;
                    graph[currentNode].push_back(counterPart);
                    degs[curDeg] = -1;
                    curDeg += 1;
                }
                degs[curDeg] = currentNode;
            }
            // todo:
            graph[whichNode].clear();
            bestMax[m] = 0;
            // todo:
            for (auto &child : sets[m]) {
                bestMax[m] = max(bestMax[m], information[child].value);
            }
            for (int i = 0; i <= logs[information[whichNode].subTree]; ++ i) {
                if (degs[i] != -1) {
                    sets[m].push_back(degs[i]);
                    bestMax[m] = max(bestMax[m], information[degs[i]].value);
                }
            }
        }
        else {
            int a, b;
            cin >> a >> b;
            if (sets[a].size() < sets[b].size()) {
                sets[a].swap(sets[b]);
            }
            bestMax[a] = max(bestMax[a], bestMax[b]);
            for (auto &elem : sets[b]) {
                sets[a].push_back(elem);
            }
        }
    }
    return 0;
}