#include "meetings.h"
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int zli = 1;
vector<int> group[100'000];
vector<int> path[2'002];
vector<int> under[2'002];
// int parent[2'000];
// int centr[2'000];
int done[2'002];
vector <int> graph[2'002];
mt19937 gen(1);
int draw_new(vector<int> &vec, int dn)
{
int lim = vec.size();
int v = vec[gen()%lim];
while (done[v] == dn)
{
v = vec[gen()%lim];
}
return v;
}
pair<int, int> rec_path(int up, int down, int id) // zwraca najnizszy i najwyzszy
{
if (group[id].size() == 1)
{
return {group[id][0], group[id][0]};
}
int led = draw_new(group[id], -2);
int ld = zli+1;
int hd = zli+2;
zli+=2;
for (auto i : group[id])
{
if (i == led)break;
int a = Query(i, led, down);
if (a == i)
{
group[ld].push_back(i); // niższa
}
else if (a == led)
{
group[hd].push_back(i); // wyzsza
}
else assert(false);
}
int u, d;
if (group[hd].empty())
{
graph[up].push_back(led);
graph[led].push_back(up);
u = led;
}
else
{
auto h = rec_path(up, led, hd);
graph[h.first].push_back(led);
graph[led].push_back(h.first);
u = h.second;
}
if (group[ld].empty())
{
graph[led].push_back(down);
graph[down].push_back(led);
d = led;
}
else{
auto l = rec_path(led, down, ld);
graph[led].push_back(l.second);
graph[l.second].push_back(led);
d = l.first;
}
return {d, u};
}
void solve_path(int v, int p)
{
if (path[v].empty())
{
graph[p].push_back(v);
graph[v].push_back(p);
return;
}
shuffle(path[v].begin(), path[v].end(), gen);
for (auto i : path[v])
{
group[zli+1].push_back(i);
}
zli++;
auto a = rec_path(p, v, zli);
graph[a.first].push_back(v);
graph[v].push_back(a.first);
graph[p].push_back(a.second);
graph[a.second].push_back(p);
}
void divide_under(int p)
{
if (under[p].empty())
{
return;
}
if (under[p].size() == 1)
{
graph[p].push_back(under[p][0]);
graph[under[p][0]].push_back(p);
return;
}
shuffle(under[p].begin(), under[p].end(), gen);
// int v = draw_new(under[p], p);
// done[v] = p;
vector<int> fract = {};
for (auto i : under[p])
{
if (done[i] == p)continue;
bool found = 0;
for (auto f : fract)
{
// int f = fract[j];
int a = Query(i, f, p);
if (a == p)//w innej spojnej
{
continue;
}
if (a == f)
{
under[f].push_back(i);
found = 1;
break;
}
else
{
if (done[a] != p)
{
done[a] = p;
path[f].push_back(a);
}
if(i != a)under[a].push_back(i);
found = 1;
break;
}
}
done[i] = p;
if (!found)fract.push_back(i);
}
for (auto f : fract)
{
solve_path(f, p);
divide_under(f);
for (auto i : path[f])
{
divide_under(i);
}
}
}
set<pair<int,int>> o;
void Solve(int N) {
// int x = Query(0, 1, 2);
// for (int u = 0; u < N - 1; ++u) {
// Bridge(u, u + 1);
// }
int r = gen()%N;
for (int i = 0; i < N; i++)
{
done[i] = -1;
if (r == i)continue;
under[r].push_back(i);
}
divide_under(r);
for (int i = 0; i < N; i++)
{
for (auto v : graph[i])
{
if (i < v && !o.contains({i, v}))
{
Bridge(i, v);
o.insert({i, v});
}
}
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |