canuc80k2345·46/50

Thống Kê Nhãn Trong Nhóm

Nộp bài trên LQDOJ

Bài 23 · Disjoint Set Union

Có phần tử, phần tử mang nhãn và ban đầu đứng riêng. Xử lý thao tác hợp nhóm hoặc đếm một nhãn trong nhóm.

Input

  • Dòng đầu chứa và .
  • Dòng thứ hai chứa nhãn .
  • dòng tiếp theo là để hợp hai nhóm hoặc để đếm nhãn trong nhóm chứa .

Output

  • Với mỗi truy vấn loại , in số phần tử mang nhãn trong nhóm chứa .

Constraints

  • .
  • .
  • Hợp hai phần tử đã cùng nhóm không làm thay đổi trạng thái.

Scoring

  • Subtask ( số điểm): .
  • Subtask ( số điểm): Không có giới hạn bổ sung.

Example

Test 1

Input

6 8
1 2 1 3 2 1
2 1 2
1 1 3
2 1 1
1 2 5
1 1 2
2 5 1
2 4 3
2 4 1

Output

0
2
2
1
0

Giải thích: Ban đầu nhóm của không có nhãn . Sau khi hợp , nhãn xuất hiện hai lần; khi hợp thêm , nhóm mới vẫn có đúng hai phần tử nhãn . Phần tử đứng riêng và mang nhãn .

Lời giải tóm tắt
  • DSU quản lý các nhóm. Mỗi gốc giữ bảng tần suất nhãn của toàn bộ nhóm đó.
  • Khi gộp hai nhóm khác nhau, chuyển các mục của bảng nhỏ hơn sang bảng lớn hơn; cộng số lượng nếu nhãn đã có. Xóa bảng ở gốc cũ.
  • Truy vấn tìm gốc của phần tử rồi đọc số lần xuất hiện của nhãn; không có trong bảng thì trả 0. Bất biến bảng ở gốc luôn đúng vì phép gộp cộng đủ hai nhóm rời nhau.
  • Gộp nhỏ vào lớn giới hạn tổng công việc trên các bảng. Với unordered_map có thao tác trung bình O(1), cận O((N+Q) log N) là đủ cho cách cài đặt; bộ nhớ O(N).