Título:
Necesidad de mantener una colección de verificación y eliminación de banda persistente.
Ideas de resolución de problemas:
Si la estructura de datos persistentes no se ve obligada a estar en línea, intente construir un árbol secuencial en el tiempo fuera de línea, y luego proceselo directamente, y luego retroceda después de resolver un hijo. Debido a la necesidad de retroceder, la búsqueda de unión aquí no usa compresión de ruta, sino fusión heurística.
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 50;
struct node{
int op, a, b;
}e[maxn];
vector<int> g[maxn];
int n, m;
int h[maxn*2], fa[maxn*2], sz[maxn*2], to[maxn], tot;
int fnd(int x){
if(fa[x] == x) return x;
return fnd(fa[x]);
}
int ans[maxn];
void dfs(int u){
int op = e[u].op, a = e[u].a, b = e[u].b;
if(op == 4){
if(to[a] == -1 || to[b] == -1) ans[u] = 0;
else {
int ra = fnd(to[a]), rb = fnd(to[b]);
ans[u] = (ra == rb);
}
}else if(op == 5){
if(to[a] == -1) ans[u] = 0;
else{
int ra = fnd(to[a]);
ans[u] = sz[ra];
}
}
for(int i = 0; i < g[u].size(); ++i){
int v = g[u][i];
op = e[v].op, a = e[v].a, b = e[v].b;
if(op == 1){
if(to[a] == -1 || to[b] == -1){
dfs(v); continue;
}
int ra = fnd(to[a]), rb = fnd(to[b]);
if(ra == rb){
dfs(v); continue;}
if(h[ra] == h[rb]){
fa[rb] = ra; sz[ra] += sz[rb]; h[ra]++;
dfs(v);
fa[rb] = rb; sz[ra] -= sz[rb]; h[ra]--;
}else{
if(h[ra] < h[rb]) swap(ra, rb);
fa[rb] = ra; sz[ra] += sz[rb];
dfs(v);
fa[rb] = rb; sz[ra] -= sz[rb];
}
}else if(op == 2){
int t = to[a];
if(to[a] == -1){
dfs(v); continue;}
int ra = fnd(to[a]);
to[a] = -1;
sz[ra]--;
dfs(v);
to[a] = t;
sz[ra]++;
}else if(op == 3){
if(to[a] == -1 || to[b] == -1){
dfs(v); continue;}
int ra = fnd(to[a]), rb = fnd(to[b]);
if(ra == rb){
dfs(v); continue;}
int t = to[a];
to[a] = ++tot;
sz[to[a]] = 1;
sz[ra]--;
//out
fa[to[a]] = rb;
sz[rb]++;
//join
dfs(v);
sz[rb]--;
sz[ra]++;
to[a] = t;
}
else dfs(v);
}
}
int main()
{
cin>>n>>m;
for(int i = 1; i <= m; ++i){
int op, k, a, b = 0; scanf("%d%d%d", &op, &k, &a);
g[k].push_back(i);
if(op != 2 && op != 5) scanf("%d", &b);
e[i] = (node){
op, a, b};
}
for(int i = 1; i <= n; ++i) to[i] = i, fa[i] = i, sz[i] = 1;
tot = n;
dfs(0);
for(int i = 1; i <= m; ++i){
if(e[i].op == 4) {
if(ans[i] == 0) puts("No");
else puts("Yes");
}
else if(e[i].op == 5){
printf("%d\n", ans[i]);
}
}
}