考点: 并查集
思路:倒序模拟,先存储所有的修改查询,如果\(op = 2\), 把更新值的祖宗结点给被更新值的祖宗节点,如果\(op = 1\) 就把添加元素的祖宗结点添上。
#include <iostream>
using namespace std;
const int N = 5e5 + 10;
int p[N];//p的在祖宗结点
int n;
int a[N], b[N], q[N];
int find(int x){//求x的祖宗结点
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
int main(){
for(int i = 1; i <= N - 5; i ++ ) p[i] = i;
scanf("%d",&n);
int cnt = 1;
int op;
for(int i = 1; i <= n; i ++ ){
scanf("%d",&op);
if(op == 1) scanf("%d",&a[i]);
else scanf("%d %d",&a[i], &b[i]);
}
for(int i = n; i >= 1; i -- ){
if(b[i] == 0) q[cnt ++] = p[a[i]] ;//祖宗结点就是答案
else p[a[i]] = p[b[i]];//合并集合,把祖宗结点合并
}
for(int i = cnt - 1; i >= 1; i -- ) cout << q[i] << " ";
puts("");
return 0;
}