Va 11987 Almost Union-Find (weighted sum query set)

Source: Internet
Author: User

Problem AAlmost Union-Find

I hope you know the beautiful Union-Find structure. In this problem, you're trying to implement something similar, but not identical.

The data structure you need to write is also a collection of disjoint sets, supporting 3 operations:

1 p q

Union the sets containing p and q. If p and q are already in the same set, ignore this command.

2 p q

Move p to the set containing q. If p and q are already in the same set, ignore this command

3 p

Return the number of elements and the sum of elements in the set containing p.

Initially, the collection contains n sets: {1}, {2}, {3},..., {n }.

Input

There are several test cases. each test case begins with a line containing two integers n and m (1 <= n, m <= 100,000), the number of integers, and the number of commands. each of the next m lines contains a command. for every operation, 1 <= p, q <= n. the input
Is terminated by end-of-file (EOF). The size of input file does not exceed 5 MB.

Output

For each type-3 command, output 2 integers: the number of elements and the sum of elements.

Sample Input
5 71 1 22 3 41 3 53 42 4 13 43 3
Output for the Sample Input
3 123 72 8
Explanation

Initially: {1}, {2}, {3}, {4}, {5}

Collection after operation 1 1 2: {1, 2}, {3}, {4}, {5}

Collection after operation 2 3 4: {1, 2}, {3, 4}, {5} (we omit the empty set that is produced when taking out 3 from {3 })

Collection after operation 1 3 5: {1, 2}, {3, 4, 5}

Collection after operation 2 4 1: {1, 2}, {3, 5}

Rujia Liu's Present 3: A Data Structure Contest Celebrating the 100th Anniversary of Tsinghua University
Special Thanks: Yiming Li
Note: Please make sure to test your program with the gift I/O files before submitting!

This question was inspired by luyuncheng.

The difficulty of this question lies in 2:
You need to move an element from one set to another.
We know that the query set cannot delete elements, because the entire structure is unidirectional and we do not know what the son is.
However, moving elements here actually involves the deletion operation. What should we do?
There is an idea that may soon come to mind that you do not actually Delete the element p to be moved, that is, do not change the original path of the p set, however, the weights of the set need to be changed (equivalent to p as a virtual point), and then p is directly "mounted to" q's set.
Note: here we must ensure that p can only serve as one leaf in the future and cannot be a father. Otherwise, it will overwrite the original path (as a father, in addition, it can prove that the practice of only leaf exists.
Note the following points when writing a program:
1. Let the values of each element have two-dimensional states. One Dimension is used for saving. This element is stored in the first set, and the other one stores the actual situation of this element.
2. When merging, pay attention to the change of the weight value, which one-dimensional state should be used.
3. When you find (), first determine whether the element exists in the past and present states, and then select different search paths, and there are also some differences in writing path compression.

For details, see the code:

# Include <cstdio> struct Node {int fa [2], num [2], value [2];} ele [100005]; void init () {for (int I = 0; I <100005; I ++) {ele [I]. fa [0] = I; ele [I]. fa [1] =-1; ele [I]. num [0] = 1; ele [I]. num [1] = 0; ele [I]. value [0] = I; ele [I]. value [1] = 0 ;}} int find (int n) {if (ele [n]. fa [1] =-1) {int r = ele [n]. fa [0]; while (ele [r]. fa [0]! = R) r = ele [r]. fa [0]; int f = ele [n]. fa [0]; while (f! = R) {int tem = ele [f]. fa [0]; ele [f]. fa [0] = r; f = tem;} return r;} else {int f = ele [n]. fa [1]; while (ele [f]. fa [0]! = F) {f = ele [f]. fa [0];} ele [n]. fa [1] = f; return f ;}} int n, m; int main () {while (scanf ("% d", & n, & m )! = EOF) {init (); while (m --) {int ope, p, q; scanf ("% d", & ope); if (ope = 1) {scanf ("% d", & p, & q); int f1 = find (p); int f2 = find (q); if (f1! = F2) {ele [f1]. fa [0] = f2; ele [f2]. num [0] + = ele [f1]. num [0]; ele [f2]. value [0] + = ele [f1]. value [0] ;}} else if (ope = 2) {scanf ("% d", & p, & q); int f1 = find (p ); int f2 = find (q); // forget to add if (f1! = F2). It slowed down some ele [f1]. num [0] --; ele [f1]. value [0]-= p; ele [p]. fa [1] = f2; ele [f2]. num [0] ++; ele [f2]. value [0] + = p;} else {scanf ("% d", & p); int f = find (p ); printf ("% d \ n", ele [f]. num [0], ele [f]. value [0]) ;}} return 0 ;}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.