Problem Description:
The first behavior is two integers: N and m represent the number of start sets and the number of commands respectively.
Initialize each set with only one element, from 1 to n altogether n sets, and the value of that element inside the first set is I.
There are three commands: the 1 command followed by two parameters p,q represents merging the set of P and Q.
The 2 command also has two parameters, assuming that P,Q represents p being taken out of its own set separately and placed in the Q set.
1 command If P,Q is already inside the same set, ignore this command, and the 2 command is the same.
The 3 command is a query command followed by a parameter p, which queries the number of elements in the set of P and the sum of all the elements.
Sample Input
5 7
1 1 2
2 3 4
1 3 5
3 4
2 4 1
3 4
3 3
Sample Output
3 12
3 7
2 8
Code ideas:
This problem because the maximum value of N and M is 1e5 and the time limit is 1s, so the set of two layer cycle will be tle.
This problem will use a small trick:
When the 2 command is moved to the root node, it will time out if each child node is traversed to make a change. At this time, we can not move him, let him still go to store the current collection of information,
Instead, use a node other than n to move it. When querying this node it is possible to find the node (because if the point is moved, it is not possible to become the root node again, so the value of d[] does not change too many times), so we need an array to store the next corner of the corresponding node (scapegoat) where, in the code I use d[].
#include <stdio.h>#include<string.h>#include<stdlib.h>#defineMAX 100000intn,m;intpre[2*max+7],d[max+7],sum[max+7],num[max+7];voidinit () { for(intI=1; i<=max;i++) {Pre[i]=i; Sum[i]=i; Num[i]=1; D[i]=i; }}intFindintx) { intR=x; while(r!=Pre[r]) r=Pre[r]; intI=x,j; while(i!=R) {J=Pre[i]; Pre[i]=R; I=J; } returnR;}voidMixintXintYintOpera) { intfx=find (d[x]); intfy=find (D[y]); if(fx!=y) { if(opera==1) {Num[fy]+=NUM[FX]; SUM[FY]+=SUM[FX]; NUM[FX]=0; SUM[FX]=0; PRE[FX]=fy; } Else{NUM[FX]--; SUM[FX]-=x; NUM[FY]++; SUM[FY]+=x; D[X]=x+MAX; PRE[D[X]]=fy; } }}intMain () { while(SCANF ("%d%d", &n,&m)! =EOF) {init (); for(intI=1; i<=m;i++) { intOpera; scanf ("%d",&Opera); if(opera==1|| opera==2) { intx, y; scanf ("%d%d",&x,&y); Mix (X,y,opera); } Else { intx; scanf ("%d",&x); introot=find (d[x]); printf ("%d%d\n", Num[root],sum[root]); } } } return 0;}
UVA 11987 almost Union-find (and set of five)