题目
题解思路
这里用到了类似懒标记的东西,用来解决查询固定之前那一列的元素的个数。
如果我们不加以这个标记,只用w来记录这个节点到根节点的距离,如果他不之间给你一列的最后一个元素,这样普通的情况就出问题了。
所以我们施加的懒标记来解决无法直接得到一列的元素个数。
再接入新一列的时候,直接让原来根节点的w变成新一列的懒标记。
而新一列的懒标记就可以加上并入那一列的标记了。
这样find的时候值自然就被更新了。
而且find完了是直接连接根节点的。
不用担心+=带来的自增影响。
太巧妙了。
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 30010 ;
int a[N] , w[N] , sz[N] ;
int find2(int x )
{
if ( x != a[x] )
{
int t = a[x];
a[x] = find2(a[x]);
w[x] += w[t];
}
return a[x];
}
int main ()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
for (int i = 1 ; i <= N -5 ; i++ )
{
a[i] = i ;
sz[i] = 1 ;
}
for (int i = 1 ; i <= n ; i++ )
{
string s;
int t1,t2;
cin>>s>>t1>>t2;
if ( s == "M" )
{
int fx = find2(t1) ;
int fy = find2(t2) ;
a[fx] = fy ;
w[fx] = sz[fy];
sz[fy] += sz[fx];
}else
{
if ( find2(t1) == find2(t2))
cout<<max( abs(w[t1]-w[t2]) -1 , 0 ) <<"\n";
else
cout<<"-1\n";
}
}
return 0 ;
}