Pagini recente » Cod sursa (job #1053264) | Cod sursa (job #13065) | Cod sursa (job #312881) | Cod sursa (job #1278309) | Cod sursa (job #3165076)
#include <fstream>
#include <vector>
using namespace std;
/// Heap Binomial
const int NMAX = 1e2;
const int QMAX = 3e5;
const int LOGQMAX = 19;
struct ArboreBinomial
{
int valoare;
int dimensiune;
vector<ArboreBinomial*> fii;
ArboreBinomial(int valoare) :
valoare(valoare), dimensiune(0) {}
~ArboreBinomial()
{
for (int i = 0; i < this->fii.size(); ++i)
{
delete this->fii[i];
}
}
};
ArboreBinomial* multimi[1 + NMAX][1 + LOGQMAX];
int maxim(int index) /// avem garantia din input ca apelam asta cand multimea are macar un element
{
int maxim = INT_MIN;
int indexMaxim = -1;
for (int i = 0; i < LOGQMAX; ++i)
{
if (multimi[index][i] != nullptr)
{
if (maxim < multimi[index][i]->valoare)
{
maxim = multimi[index][i]->valoare;
indexMaxim = i;
}
}
}
vector<ArboreBinomial*> fii = multimi[index][indexMaxim]->fii;
ArboreBinomial* carry = nullptr;
ArboreBinomial* newCarry = nullptr;
multimi[index][indexMaxim]->fii.clear();
delete multimi[index][indexMaxim];
multimi[index][indexMaxim] = nullptr;
int indexFii = 0;
for (int i = 0; i < LOGQMAX; ++i)
{
newCarry = nullptr;
if (indexFii < fii.size() && i == fii[indexFii]->dimensiune)
{
if (multimi[index][i] == nullptr)
{
if (carry == nullptr)
{
multimi[index][i] = fii[indexFii];
}
else
{
ArboreBinomial* arbore1 = carry;
ArboreBinomial* arbore2 = fii[indexFii];
if (arbore1->valoare < arbore2->valoare)
swap(arbore1, arbore2);
arbore1->fii.emplace_back(arbore2);
++arbore1->dimensiune;
newCarry = arbore1;
}
}
else
{
ArboreBinomial* arbore1 = multimi[index][i];
ArboreBinomial* arbore2 = fii[indexFii];
if (arbore1->valoare < arbore2->valoare)
swap(arbore1, arbore2);
arbore1->fii.emplace_back(arbore2);
++arbore1->dimensiune;
newCarry = arbore1;
multimi[index][i] = nullptr;
if (carry)
{
multimi[index][i] = carry;
}
}
++indexFii;
}
else
{
if (carry != nullptr)
{
if (multimi[index][i] == nullptr)
{
multimi[index][i] = carry;
}
else
{
ArboreBinomial* arbore1 = multimi[index][i];
ArboreBinomial* arbore2 = carry;
if (arbore1->valoare < arbore2->valoare)
swap(arbore1, arbore2);
arbore1->fii.emplace_back(arbore2);
++arbore1->dimensiune;
newCarry = arbore1;
multimi[index][i] = nullptr;
}
}
}
carry = newCarry;
}
return maxim;
}
void insereaza(int index, int x)
{
ArboreBinomial* carry = new ArboreBinomial(x);
ArboreBinomial* newCarry = nullptr;
for (int i = 0; i < LOGQMAX; ++i)
{
newCarry = nullptr;
if (multimi[index][i] == nullptr)
{
multimi[index][i] = carry;
}
else
{
if (carry != nullptr)
{
ArboreBinomial* arbore1 = multimi[index][i];
ArboreBinomial* arbore2 = carry;
if (arbore1->valoare < arbore2->valoare)
swap(arbore1, arbore2);
arbore1->fii.emplace_back(arbore2);
++arbore1->dimensiune;
newCarry = arbore1;
multimi[index][i] = nullptr;
}
}
carry = newCarry;
}
}
void uneste(int index1, int index2)
{
ArboreBinomial* carry = nullptr;
ArboreBinomial* newCarry = nullptr;
for (int i = 0; i < LOGQMAX; ++i)
{
newCarry = nullptr;
if (multimi[index1][i] == nullptr && multimi[index2][i] == nullptr)
{
if (carry != nullptr)
{
multimi[index1][i] = carry;
}
}
else if (multimi[index1][i] == nullptr && multimi[index2][i] != nullptr)
{
if (carry == nullptr)
{
multimi[index1][i] = multimi[index2][i];
}
else
{
ArboreBinomial* arbore1 = carry;
ArboreBinomial* arbore2 = multimi[index2][i];
if (arbore1->valoare < arbore2->valoare)
swap(arbore1, arbore2);
arbore1->fii.emplace_back(arbore2);
++arbore1->dimensiune;
newCarry = arbore1;
}
}
else if (multimi[index1][i] != nullptr && multimi[index2][i] == nullptr)
{
if (carry != nullptr)
{
ArboreBinomial* arbore1 = carry;
ArboreBinomial* arbore2 = multimi[index1][i];
if (arbore1->valoare < arbore2->valoare)
swap(arbore1, arbore2);
arbore1->fii.emplace_back(arbore2);
++arbore1->dimensiune;
newCarry = arbore1;
multimi[index1][i] = nullptr;
}
}
else
{
if (carry == nullptr)
{
ArboreBinomial* arbore1 = multimi[index2][i];
ArboreBinomial* arbore2 = multimi[index1][i];
if (arbore1->valoare < arbore2->valoare)
swap(arbore1, arbore2);
arbore1->fii.emplace_back(arbore2);
++arbore1->dimensiune;
newCarry = arbore1;
multimi[index1][i] = nullptr;
}
else
{
ArboreBinomial* arbore1 = multimi[index2][i];
ArboreBinomial* arbore2 = multimi[index1][i];
if (arbore1->valoare < arbore2->valoare)
swap(arbore1, arbore2);
arbore1->fii.emplace_back(arbore2);
++arbore1->dimensiune;
newCarry = arbore1;
multimi[index1][i] = carry;
}
}
carry = newCarry;
}
for (int i = 0; i < LOGQMAX; ++i)
{
multimi[index2][i] = nullptr;
}
}
int main()
{
ifstream in("mergeheap.in");
ofstream out("mergeheap.out");
ios_base::sync_with_stdio(false);
in.tie(nullptr);
int n, q;
in >> n >> q;
for (int i = 1; i <= NMAX; ++i)
for (int j = 0; j < LOGQMAX; ++j)
multimi[i][j] = nullptr;
while (q--)
{
int tip;
in >> tip;
if (tip == 1)
{
int m, x;
in >> m >> x;
insereaza(m, x);
}
else if (tip == 2)
{
int m;
in >> m;
out << maxim(m) << '\n';
}
else
{
int a, b;
in >> a >> b;
uneste(a, b);
}
}
for (int i = 1; i <= NMAX; ++i)
{
for (int j = 0; j < LOGQMAX; ++j)
{
if (multimi[i][j] != nullptr)
{
delete multimi[i][j];
}
}
}
in.close();
out.close();
return 0;
}