Sei sulla pagina 1di 3

#include <iostream>

#include <fstream>
#include <vector>
#include <algorithm>
#include <cassert>
#include <set>
#include <limits>

using namespace std;

struct Edge {
int from, to, index;
};

struct Event {
bool opening;
Edge edge;

int point() const {


if (opening)
return edge.from;
return edge.to;
}

bool operator<(const Event& that) const {


if (point() != that.point())
return point() < that.point();
if (!opening && that.opening)
return true;
if (opening && !that.opening)
return false;

return edge.from > that.edge.from;


}
};

static const int kModulo = 666013;

void dfs(const vector< vector<int> > &edges, vector<int> &colors, int node) {
for (auto &neighbor : edges[node]) {
assert(colors[neighbor] != colors[node]);
if (colors[neighbor] == 0) {
colors[neighbor] = 3 - colors[node];
dfs(edges, colors, neighbor);
}
}
}

int main() {
ifstream cin("aquapark.in");
ofstream cout("aquapark.out");

int type; assert(cin >> type);


assert(1 <= type && type <= 2);

int N, M; assert(cin >> N >> M);


assert(1 <= N && N <= 75 * 1000);
assert(1 <= M && M <= 100 * 1000);
vector<Event> events;
events.reserve(M * 2);
vector<Edge> edges(M);
for (int i = 0; i < M; ++i) {
int x, y; assert(cin >> x >> y);
assert(1 <= x && x <= N);
assert(1 <= y && y <= N);
assert(x != y);
if (x > y)
swap(x, y);
edges[i] = Edge{x, y, i};
}

sort(edges.begin(), edges.end(), [&](const Edge& a, const Edge& b) {


return a.to > b.to;
});
for (int i = 0; i < M; ++i) {
edges[i].index = i;
events.push_back(Event{true, edges[i]});
events.push_back(Event{false, edges[i]});
}

sort(edges.begin(), edges.end(), [&](const Edge& a, const Edge& b) {


if (a.from != b.from)
return a.from < b.from;
return a.to < b.to;
});

vector< vector<int> > conflict(M);


int answer = 0;
for (int i = 1; i < M; ++i) {
if (edges[i].from == edges[i - 1].from && edges[i].to == edges[i - 1].to) {
conflict[edges[i].index].push_back(edges[i - 1].index);
conflict[edges[i - 1].index].push_back(edges[i].index);
--answer;
}
if (i > 0)
assert(edges[i - 1].from != edges[i].from || edges[i - 1].to !=
edges[i].to);
}

sort(events.begin(), events.end());
set<pair<int, int> > S;
for (auto &event : events) {
if (event.opening)
S.emplace(event.edge.from, event.edge.index);
else {
bool kept = false;
for (auto it = S.upper_bound(make_pair(event.edge.from,
numeric_limits<int>::max())), jt = it; it != S.end(); it = jt) {
jt = it;
++jt;

conflict[event.edge.index].push_back(it->second);
conflict[it->second].push_back(event.edge.index);
if (kept)
S.erase(it);
else
kept = true;
}
S.erase(make_pair(event.edge.from, event.edge.index));
}
}

vector<int> colors(M, 0);


for (int i = 0; i < M; ++i)
if (colors[i] == 0) {
colors[i] = 1;
dfs(conflict, colors, i);
++answer;
}

if (type == 1) {
for (auto &edge : edges)
cout << edge.from << " " << edge.to << " " << colors[edge.index] <<
"\n";
} else {
int as_power = 1;
for (int i = 0; i < answer; ++i)
as_power = (2 * as_power) % kModulo;
cout << as_power << "\n";
}
}

Potrebbero piacerti anche