删除操作:
找一个新点代替旧点,,之后对旧点的所有操作都转移到新点上来。旧点的影响消失。
#pragma warning(disable:4996)
#include <cstdio>
#define N 200001
using namespace std;
int sum[N], cnt[N], fa[N], id[N];
int SIZE;
void init(int n){
for (int i = 0; i <= n; i++){
sum[i] = fa[i] = id[i] = i;
cnt[i] = 1;
}
SIZE = n;
}
int find(int x){
if (x == fa[x])return fa[x];
return fa[x] = find(fa[x]);
}
void union1(int x, int y){
int fx = find(x), fy = find(y);
if (fx == fy)return;
fa[fx] = fy;
sum[fy] += sum[fx];
cnt[fy] += cnt[fx];
}
void move(int x){
int fx = find(id[x]);
sum[fx] -= x;
cnt[fx]--;
SIZE++;
id[x] = SIZE;
fa[SIZE] = SIZE;
sum[SIZE] = x;
cnt[SIZE] = 1;
}
void query(int x){
int fx = find(x);
printf("%d %d\n", cnt[fx], sum[fx]);
}
int main(){
int n, m;
while (scanf("%d %d", &n, &m) != EOF){
init(n);
for (int i = 0; i < m; i++){
int type;
scanf("%d", &type);
if (type == 1){
int a, b;
scanf("%d %d", &a, &b);
union1(id[a], id[b]);
}
else if (type == 2){
int a, b;
scanf("%d %d", &a, &b);
if (find(id[a]) != find(id[b])){
move(a);
union1(id[a], id[b]);
}
}
else if (type == 3){
int x;
scanf("%d", &x);
query(id[x]);
}
}
}
return 0;
}