题意
如果Y不在X所在的对立里的话,将Y所在的队列插入到X所在的队列后面,并询问某个人后面有多少人。
题解
使用并查集,将一个队伍插入到另一个队伍后面,将会改变一个队伍里面某个人后面的人数值,如果暴力修改很耗时间,所以采用并查集的做法,两个队伍合并的时候,将X的队尾连上Y的队头,这时候知道X的后面的人数便是Y里面的人数,那X队伍里面的人呢?这时候就用到了并查集路径压缩的过程。
在路径压缩的过程中,首先先记录下此时的pre[x],例如要压缩3的路径,pre[x] = find(pre[x]),压缩后pre[3] = 1,但是压缩的过程是会经过2的,首先在pre[x] = find(pre[x])之前记录下当前的pre[x] = 2,当pre[x] = find(pre[x])结束后,2结点的值已经被1结点更新了,所以这时可以将2结点的信息再更新到3上面。
ans[i]: i后面有多少人, num[i]: i所在的队列有多少人
int fx = find(x), fy = find(y);
if(fx != fy) {
pre[fx] = fy;
ans[fx] = num[fy];
num[fy] += num[fx];
}
int find(int x) {
if(x == pre[x])
return x;
int tmp = pre[x];
pre[x] = find(pre[x]);
ans[x] += ans[tmp];
return pre[x];
}