始终 TLE 最后四个点……
#include <bits/stdc++.h>
using namespace std;
inline void train() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
bool merge(int a, int b);
void check_delegation(int faq);
int query(int x);
inline int maxi(int a, int b) {
return a > b ? a : b;
}
inline int mini(int a, int b) {
return a < b ? a : b;
}
constexpr int N = 6e5+4;
int n,m;
int fa[N], priority[N], sz[N];
bool vis[N];
// first: delegate requirement; second: delegate target
struct dream {
int required, a, b;
dream() {
}
dream(int required, int a, int b) : required(required), a(a), b(b) {
}
};
//list<dream> delegates[N];
vector<dream> delegates[N];
queue<pair<int, int> > scheduled;
void execute() {
while (!scheduled.empty()) {
auto sf = scheduled.front();
scheduled.pop();
//// cerr << "calling merger from delegation " << endl;
merge(sf.first, sf.second);
// merge(scheduled.front().first, scheduled.front().second);
//
}
}
void check_delegation(int faq) {
vector<dream> tmp;
for (auto it = delegates[faq].begin(); it != delegates[faq].end(); it++) {
// cerr << "dream: activate " << it->a << " and " << it->b << " for " << it->required << endl;
if (query(it->a) == query(it->b)) {
// cerr << "came true, erased\n";
// it = delegates[faq].erase(it);
} else if (query(it->required) == faq) {
dream tmp = *it;
// cerr << "scheduled\n";
// it = delegates[faq].erase(it);
scheduled.push(make_pair(tmp.a, tmp.b));
} else {
tmp.push_back(*it);
// it++;
}
}
delegates[faq] = tmp;
// swap(tmp, delegates[faq]);
// cerr << "end delegation check, current size " << scheduled.size() << "\n";
// for (auto &e : scheduled) {
// merge(e.first, e.second);
// }
}
int query(int x) {
// cerr << "querying " << x << endl;
if (fa[x] == x) {
return x;
}
else {
int q = query(fa[x]);
// Conduct on-the-way merge. In a tree, so no stimulation
fa[x] = q;
// check_delegation(x);
// for (auto &i : delegates[x]) delegates[q].push_back(i);
// delegates[x].clear();
return q;
}
}
// Return if left side not loses (cleaned)
bool merge(int a, int b) {
// cerr << "merging " << a << " and " << b << endl;
int qa = query(a), qb = query(b), faq;
if (qa == qb) return true;
bool result;
if (delegates[qa].size() > delegates[qb].size()) {
// cerr << qb << " into " << qa << endl;
sz[qa] += sz[qb];
fa[qb] = qa;
result = true;
faq = qa;
} else {
// cerr << qa << " into " << qb << endl;
sz[qb] += sz[qa];
fa[qa] = qb;
result = false;
faq = qb;
}
// cerr << "checking delegation of " << faq << endl;
check_delegation(faq);
if (result) {
for (auto &i : delegates[qb]) delegates[qa].push_back(i);
delegates[qb].clear();
} else {
for (auto &i : delegates[qa]) delegates[qb].push_back(i);
delegates[qa].clear();
}
return result;
}
int main() {
train();
cin>>n>>m;
for (int i = 1; i <= n; i++) {
fa[i] = i;
// priority[i] = rand_src(); // We have to dream big!!!!
sz[i] = 1;
}
for (int i = 1; i <= m; i++) {
int op,a,b,c,d;
cin>>op;
switch (op) {
case 1:
cin>>a>>b>>c>>d;
// Immediate trigger
if (query(a) == query(b)) {
merge(c,d);
execute();
vis[i] = true;
}
else {
// Single-side placement, toggle randomization ?
a = query(a); b = query(b);
if (delegates[a].size() > delegates[b].size()) {
// cerr << "delegate put into " << a << endl;
delegates[a].push_back(dream(b, c, d));
} else {
// cerr << "delegate put into " << b << endl;
delegates[b].push_back(dream(a, c, d));
}
}
break;
case 2:
cin>>a>>b;
merge(a,b);
execute();
break;
case 3:
cin>>a>>b;
// cerr<<"***** ";
if (query(a) == query(b)) cout<<"entangled\n";
else cout<<"separate\n";
break;
case 4:
cin>>a;
// cerr<<"***** ";
cout<<sz[query(a)]<<'\n';
break;
}
}
cout<<flush;
return 0;
}