| # | Time | Username | Problem | Language | Result | Execution time | Memory |
|---|---|---|---|---|---|---|---|
| 1351585 | Alex1298 | ICC (CEOI16_icc) | C++20 | 0 ms | 0 KiB |
#include <bits/stdc++.h>
#include "icc.h"
using namespace std;
int n;
int tata[105];
int dim[105];
int roots[105];
vector<int> nodes[105];
int incercat[105];
int a[105];
int b[105];
int temp[105];
int dir[105];
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rad(int x)
{
if(x == tata[x])
{
return x;
}
int r = rad(tata[x]);
tata[x] = r;
return r;
}
void unire(int x, int y)
{
int rx = rad(x);
int ry = rad(y);
if(rx == ry)
{
exit(1);
}
if(dim[ry] > dim[rx])
{
swap(rx, ry);
}
tata[ry] = rx;
dim[rx] += dim[ry];
}
int ask_nodes(int st, int mij1, int mij2, int dr)
{
int inda = 0;
int indb = 0;
for(int i = st; i<=mij1; i++)
{
a[inda] = temp[i];
inda++;
}
for(int i = mij2; i<=dr; i++)
{
b[indb] = temp[i];
indb++;
}
return query(inda, indb, a, b);
}
pair<int, int> find_edge()
{
for(int i = 1; i<=n; i++)
{
nodes[i].clear();
incercat[i] = 0;
}
int cnt = 0;
for(int i = 1; i<=n; i++)
{
if(i == rad(i))
{
cnt++;
roots[cnt] = i;
}
nodes[rad(i)].push_back(i);
}
int poz = -1;
int max_bits = 0;
while((1 << max_bits) < cnt) {
max_bits++;
}
for(int b = 0; b < max_bits; b++) {
int inda = 0;
int indb = 0;
for(int i = 1; i <= cnt; i++) {
if((i & (1 << b)) == 0) { // Dacă bitul 'b' este 0
dir[i] = 1;
for(auto it: nodes[roots[i]]) {
a[inda] = it;
inda++;
}
} else { // Dacă bitul 'b' este 1
dir[i] = 2;
for(auto it: nodes[roots[i]]) {
b[indb] = it;
indb++;
}
}
}
// Șmecheria supremă: Dacă e ultimul bit, ȘTIM SIGUR că dă 1, nu mai consumăm query!
if(b == max_bits - 1 || query(inda, indb, a, b) == 1) {
int ind = 0;
for(int i = 1; i <= cnt; i++) {
if(dir[i] == 1) {
ind++;
temp[ind] = roots[i];
}
}
poz = ind;
for(int i = 1; i <= cnt; i++) {
if(dir[i] == 2) {
ind++;
temp[ind] = roots[i];
}
}
for(int i = 1; i <= cnt; i++) {
roots[i] = temp[i];
}
break;
}
}
if(poz == -1)
{
exit(1);
}
int ind = 0;
for(int i = 1; i<=poz; i++)
{
for(auto it: nodes[roots[i]])
{
ind++;
temp[ind] = it;
}
}
int split = ind;
for(int i = poz + 1; i<=cnt; i++)
{
for(auto it: nodes[roots[i]])
{
ind++;
temp[ind] = it;
}
}
int st = 1;
int dr = split;
int left_nod = -1;
while(st <= dr)
{
int mij = (st + dr) / 2;
if(ask_nodes(mij, split, split + 1, ind) == 1)
{
left_nod = mij;
st = mij + 1;
}
else
{
dr = mij - 1;
}
}
st = split + 1;
dr = ind;
int right_nod = -1;
while(st <= dr)
{
int mij = (st + dr) / 2;
if(ask_nodes(left_nod, split, split + 1, mij) == 1)
{
right_nod = mij;
dr = mij - 1;
}
else
{
st = mij + 1;
}
}
if(left_nod == -1 || right_nod == -1)
{
exit(1);
}
return {temp[left_nod], temp[right_nod]};
}
void run(int N)
{
n = N;
for(int i = 1; i<=n; i++)
{
tata[i] = i;
dim[i] = 1;
}
for(int i = 1; i<n; i++)
{
pair<int, int> muc = find_edge();
unire(muc.first, muc.second);
setRoad(muc.first, muc.second);
}
}
//int main()
//{
// cout << "Hello world!" << endl;
// return 0;
//}
