Official

F - BOX Editorial by en_translator


An operation of type 11 is merging sets, so it can be directly handled with the Disjoint Set Union (DSU). Thus, we want to exploit DSU to solve this problem.

First of all, we only have to consider the balls numbered up to N+QN+Q. Also, since an operation of type 11 is merging sets of balls, it seems that it is sufficient to prepare a DSU with N+QN+Q elements to handle the addition of balls.

The problem is those of type 33: “the set of many balls” may wander rapidly. (For example, the queries may ask you to put about 10510^5 balls into box 11, and then move them to boxes 2,3,2,3,\dots, and so on.) Thus, we cannot update the box that each ball belongs; otherwise it leads to TLE (Time Limit Exceeded).
Instead, we may maintain the box that each “set of balls” belongs. If we can move a set instead of balls, we would reduce the complexity.
Let us implement this solution.

The key is the function in DSU that returns the representative element, as in “leader” function in dsu in ACL (AtCoder Library).

Let us maintain the following pieces of information:

  • ld[x]=ld[x] = the representative element of the set of balls contained in box xx, or 1-1 if it is empty;
  • ing[y]=ing[y] = the box that the set represented by yy belongs to, or an indeterminate value if there is no set represented by yy.

Type 11:

  • If box YY is empty, do nothing.
  • Otherwise, if box XX is empty, move the contents of box YY to box XX as follows:
    • Let ld[X]=ld[Y]ld[X]=ld[Y], which corresponds to moving the set contained in box YY to box XX.
    • Let inv[ld[X]]=Xinv[ld[X]]=X.
    • Let ld[Y]=1ld[Y]=-1, emptying box YY.
  • Otherwise, both box XX and YY contain one or more balls, so do the following steps:
    • Merge the set represented by ld[X]ld[X] with the one represented by ld[Y]ld[Y]. Let ld[X]ld[X] be the new representative element of that set.
    • Let inv[ld[X]]=Xinv[ld[X]]=X.
    • Let ld[Y]=1ld[Y]=-1.

Type 22:
Let bb the index of the new ball.

  • If box XX is empty, let ld[X]=bld[X]=b and inv[ld[X]]=Xinv[ld[X]]=X.
  • Otherwise, merge the set of balls represented by ld[X]ld[X] with the one by bb, and let bb the representative element of the set. Then let inv[ld[X]]=Xinv[ld[X]]=X.

Type 33:
Print inv[tg]inv[tg], where tgtg is the representative element that contains ball XX.

Sample code (C++):

Copy
  1. #include<bits/stdc++.h>
  2. #include<atcoder/dsu>
  3. using namespace std;
  4. using namespace atcoder;
  5. int main(){
  6. int n,q;
  7. cin >> n >> q;
  8. dsu uf(n+q+5);
  9. int balls=n;
  10. vector<int> ld(n+1,-1);
  11. vector<int> inv(n+q+5);
  12. for(int i=1;i<=n;i++){
  13. ld[i]=i;
  14. inv[ld[i]]=i;
  15. }
  16. for(int tr=0;tr<q;tr++){
  17. int typ;
  18. cin >> typ;
  19. if(typ==1){
  20. int x,y;
  21. cin >> x >> y;
  22. if(ld[y]==-1){continue;}
  23. else if(ld[x]==-1){
  24. ld[x]=ld[y];
  25. inv[ld[x]]=x;
  26. ld[y]=-1;
  27. }
  28. else{
  29. uf.merge(ld[x],ld[y]);
  30. ld[x]=uf.leader(ld[x]);
  31. inv[ld[x]]=x;
  32. ld[y]=-1;
  33. }
  34. }
  35. if(typ==2){
  36. int x;
  37. cin >> x;
  38. balls++;
  39. if(ld[x]==-1){
  40. ld[x]=balls;
  41. inv[ld[x]]=x;
  42. }
  43. else{
  44. uf.merge(ld[x],balls);
  45. ld[x]=uf.leader(balls);
  46. inv[ld[x]]=x;
  47. }
  48. }
  49. if(typ==3){
  50. int x;
  51. cin >> x;
  52. int tg=uf.leader(x);
  53. cout << inv[tg] << "\n";
  54. }
  55. }
  56. return 0;
  57. }
#include<bits/stdc++.h>
#include<atcoder/dsu>

using namespace std;
using namespace atcoder;

int main(){
  int n,q;
  cin >> n >> q;
 
  dsu uf(n+q+5);
  int balls=n;
 
  vector<int> ld(n+1,-1);
  vector<int> inv(n+q+5);
  for(int i=1;i<=n;i++){
    ld[i]=i;
    inv[ld[i]]=i;
  }
 
  for(int tr=0;tr<q;tr++){
    int typ;
    cin >> typ;
    if(typ==1){
      int x,y;
      cin >> x >> y;
      if(ld[y]==-1){continue;}
      else if(ld[x]==-1){
        ld[x]=ld[y];
        inv[ld[x]]=x;
        ld[y]=-1;
      }
      else{
        uf.merge(ld[x],ld[y]);
        ld[x]=uf.leader(ld[x]);
        inv[ld[x]]=x;
        ld[y]=-1;
      }
    }
    if(typ==2){
      int x;
      cin >> x;
      balls++;
      if(ld[x]==-1){
        ld[x]=balls;
        inv[ld[x]]=x;
      }
      else{
        uf.merge(ld[x],balls);
        ld[x]=uf.leader(balls);
        inv[ld[x]]=x;
      }
    }
    if(typ==3){
      int x;
      cin >> x;
      int tg=uf.leader(x);
      cout << inv[tg] << "\n";
    }
  }
  return 0;
}

posted:
last update:



2025-04-09 (Wed)
07:24:07 +00:00