Pagini recente » Cod sursa (job #2977849) | Cod sursa (job #3126834) | Cod sursa (job #826906) | Cod sursa (job #350965) | Cod sursa (job #2054859)
#include <cassert>
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <memory>
using namespace std;
constexpr int64_t inf = 1e18;
class Reader {
public:
Reader(istream& _in) : in(_in), idx(kBuffSize - 1), buff(new char[kBuffSize]) { Advance(); }
Reader& operator>>(char& ch) {
ch = Current();
Advance();
return *this;
}
Reader& operator>>(char str[]) {
while (isspace(Current())) {
Advance();
}
int n = 0;
while (not isspace(Current())) {
str[n++] = Current();
Advance();
}
str[n] = 0;
return *this;
}
Reader& operator>>(string& str) {
while (isspace(Current())) {
Advance();
}
while (not isspace(Current())) {
str.push_back(Current());
Advance();
}
return *this;
}
Reader& operator>>(int32_t& value) {
bool sign = false;
while (not isdigit(Current())) {
sign |= Current() == '-';
Advance();
}
value = 0;
while (isdigit(Current())) {
value = (value << 1) + (value << 3) + (Current() - '0');
Advance();
}
value ^= (value ^ -value) & -sign;
return *this;
}
Reader& operator>>(int64_t& value) {
bool sign = false;
while (not isdigit(Current())) {
sign |= Current() == '-';
Advance();
}
value = 0;
while (isdigit(Current())) {
value = (value << 1) + (value << 3) + (Current() - '0');
Advance();
}
value ^= (value ^ -value) & -sign;
return *this;
}
Reader& operator>>(double& value) {
bool sign = false;
while (not isdigit(Current())) {
sign |= Current() == '-';
Advance();
}
value = .0;
while (isdigit(Current())) {
value = value * 10.0 + (Current() - '0');
Advance();
}
if (Current() == '.') {
Advance();
double multiplier = 0.1;
while (isdigit(Current())) {
value += (Current() - '0') * multiplier;
multiplier *= 0.1;
Advance();
}
}
if (sign) {
value = -value;
}
return *this;
}
private:
static constexpr int kBuffSize = 1 << 12;
char Current() const {
return buff[idx];
}
void Advance() {
if (++idx == kBuffSize) {
in.read(buff.get(), kBuffSize);
idx = 0;
}
}
istream& in;
int idx;
unique_ptr<char[]> buff;
};
class Printer {
public:
Printer(ostream& _out) : out(_out), idx(0), buff(new char[kBuffSize]), digits(new char[kMaxNumDigits]) { }
~Printer() { Flush(); out.flush(); }
Printer& operator<<(int32_t value) {
if (value < 0) {
PutChar('-');
value = -value;
}
int num_digits = 0;
do {
const uint32_t aux = ((uint64_t)3435973837 * value) >> 35;
digits[num_digits++] = value - (aux << 1) - (aux << 3) + '0';
value = aux;
} while (value > 0);
while (num_digits--) {
PutChar(digits[num_digits]);
}
return *this;
}
Printer& operator<<(int64_t value) {
if (value < 0) {
PutChar('-');
value = -value;
}
int num_digits = 0;
do {
const uint64_t aux = value / 10;
digits[num_digits++] = value - (aux << 1) - (aux << 3) + '0';
value = aux;
} while (value > 0);
while (num_digits--) {
PutChar(digits[num_digits]);
}
return *this;
}
Printer& operator<<(const char *str) {
for (int i = 0; str[i]; i += 1) {
PutChar(str[i]);
}
return *this;
}
Printer& operator<<(const string& str) {
for (auto&& ch : str) {
PutChar(ch);
}
return *this;
}
Printer& operator<<(const char& ch) {
PutChar(ch);
return *this;
}
Printer& operator <<(double value) {
if (value < 0) {
PutChar('-');
value = -value;
}
const int64_t integer_part = static_cast<int64_t>(value);
*this << integer_part << '.' << static_cast<int64_t>((value - integer_part) * kPrecision + 0.5);
return *this;
}
private:
static constexpr int kBuffSize = 1 << 12;
static constexpr int kMaxNumDigits = 20;
static constexpr double kPrecision = 1e9;
void Flush() {
out.write(buff.get(), idx);
}
void PutChar(const char& ch) {
buff[idx++] = ch;
if (idx == kBuffSize) {
Flush();
idx = 0;
}
}
ostream& out;
int idx;
unique_ptr<char[]> buff, digits;
};
class DisjointSets {
public:
DisjointSets(const int n) : x(n, -1) { }
bool Unite(int a, int b) {
a = FindRoot(a);
b = FindRoot(b);
if (a != b) {
if (x[b] < x[a]) {
x[b] += x[a];
x[a] = b;
} else {
x[a] += x[b];
x[b] = a;
}
return true;
}
return false;
}
int FindRoot(int node) {
return x[node] < 0 ? node : x[node] = FindRoot(x[node]);
}
private:
vector<int> x;
};
enum QueryType {
UNITE = 1,
QUERY = 2
};
int main() {
#ifdef INFOARENA
ifstream cin("disjoint.in");
ofstream cout("disjoint.out");
#endif
cin.tie(0);
ios_base::sync_with_stdio(false);
Reader r(cin); Printer p(cout);
int n, q; r >> n >> q;
DisjointSets DS(n);
while (q--> 0) {
int type, a, b; r >> type >> a >> b; a -= 1; b -= 1;
if (type == QueryType::UNITE) {
DS.Unite(a, b);
} else {
p << (DS.FindRoot(a) == DS.FindRoot(b) ? "DA" : "NU") << '\n';
}
}
return 0;
}