和hdu那题一样也是带权并查集。
考虑从最下面为根,那么根的ans = 0,路径压缩之后0就不会一直更新影响了。
然后需要注意的点,P不是点数,应该将N全初始化,就是这里一直TLE。
然后注意询问前先路径压缩一下,因为可能之前没有更新到。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 3e4+5; const int M = 1e6+5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();} return x * f; } } using namespace FASTIO; int fa[N],ans[N],sz[N]; int Find(int x) { if(x == fa[x]) return x; else { int ffa = fa[x]; fa[x] = Find(fa[x]); ans[x] = ans[ffa] + ans[x]; return fa[x]; } } int main() { int n;n = read(); for(int i = 1;i < N;++i) fa[i] = i,ans[i] = 0,sz[i] = 1; for(int i = 1;i <= n;++i) { char c;scanf("%c",&c); if(c == 'M') { int x,y;x = read(),y = read(); int xx = Find(x),yy = Find(y); if(xx != yy) { fa[xx] = yy; ans[xx] = sz[yy]; sz[yy] += sz[xx]; } } else { int x;x = read(); int ma = Find(x); printf("%d ",ans[x]); } } system("pause"); return 0; }