IOI 2012 - Rings

Xem PDF



Dạng bài
Ngôn ngữ cho phép
C, C++
Điểm: 2400 (p) Thời gian: 5.0s Bộ nhớ: 256M Input: bàn phím Output: màn hình

Một phiên bản rất sớm và khá tinh vi của chiếc dù ngày nay được mô tả trong cuốn Codex Atlanticus của Leonardo, khoảng năm \(1485\). Dù của ông gồm vải lanh kín được căng bằng một khung gỗ hình kim tự tháp. Hơn \(500\) năm sau, vận động viên nhảy dù Adrian Nicholas thử nghiệm thiết kế này, dùng một kết cấu nhẹ hiện đại để gắn dù với cơ thể.

Chúng ta muốn dùng các vòng móc nối với nhau, đồng thời làm móc cho tấm vải lanh. Mỗi vòng được làm bằng vật liệu bền và dễ uốn, có thể mở ra rồi đóng lại nên dễ dàng móc nối với các vòng khác. Một cấu hình đặc biệt là chuỗi: một dãy vòng mà mỗi vòng chỉ nối với các vòng láng giềng của nó trong dãy, nhiều nhất là hai vòng. Dãy phải có đầu và cuối, mỗi vòng ở đầu hoặc cuối nối với nhiều nhất một vòng khác. Một vòng đơn lẻ cũng là một chuỗi.

Một vòng có thể nối với ba hoặc nhiều vòng khác, nên còn có những cấu hình khác. Một vòng được gọi là then chốt nếu sau khi mở và loại bỏ nó, tất cả các vòng còn lại tạo thành một tập các chuỗi, hoặc không còn vòng nào. Nói cách khác, sau khi loại bỏ vòng đó chỉ được còn lại các chuỗi.

Yêu cầu và giao diện

Hãy đếm số vòng then chốt trong cấu hình được truyền cho chương trình. Ban đầu các vòng rời nhau; sau đó chúng được móc nối dần. Tại bất kỳ thời điểm nào, chương trình có thể được yêu cầu trả về số vòng then chốt trong cấu hình hiện tại. Bạn phải cài đặt ba chương trình con:

  • Init(N): được gọi đúng một lần lúc bắt đầu, cho biết cấu hình ban đầu có \(N\) vòng rời nhau, đánh số từ \(0\) đến \(N-1\).
  • Link(A, B): móc nối hai vòng \(A\)\(B\). Bảo đảm \(A \ne B\) và hai vòng chưa được nối trực tiếp với nhau. Ngoài ra không có điều kiện bổ sung nào, kể cả điều kiện xuất phát từ các ràng buộc vật lý. Link(A, B)Link(B, A) tương đương nhau.
  • CountCritical(): trả về số vòng then chốt trong cấu hình hiện tại.

Chi tiết cài đặt

Nộp đúng một tệp rings.c, rings.cpp hoặc rings.pas, cài đặt các chương trình con với chữ ký sau.

C/C++

C++
void Init(int N);
void Link(int A, int B);
int CountCritical();

Pascal

Delphi
procedure Init(N : LongInt);
procedure Link(A, B : LongInt);
function CountCritical() : LongInt;

Các chương trình con phải hoạt động như đã mô tả. Bạn có thể cài đặt thêm các chương trình con dùng nội bộ. Bài nộp không được giao tiếp dưới bất kỳ hình thức nào với đầu vào/đầu ra chuẩn hoặc với bất kỳ tệp nào khác.

Dữ liệu vào

Trình chấm mẫu đọc dữ liệu theo định dạng:

  • Dòng \(1\): N L.
  • Mỗi dòng từ \(2\) đến \(L+1\): số -1 để gọi CountCritical(), hoặc hai số A B làm tham số cho Link(A, B).

Dữ liệu ra

Trình chấm mẫu in tất cả các kết quả do CountCritical() trả về.

Ràng buộc

Các vòng được đánh số từ \(0\) đến \(N-1\); mỗi lần gọi Link dùng hai số vòng khác nhau và chưa nối trực tiếp. Giới hạn số vòng và số lần gọi trong từng phân nhóm được cho đầy đủ dưới đây.

Phân nhóm

Phân nhóm Điểm Điều kiện
1 20 \(N \le 5\,000\). CountCritical được gọi đúng một lần, sau tất cả các lời gọi khác. Link được gọi không quá \(5\,000\) lần.
2 17 \(N \le 1\,000\,000\). CountCritical được gọi đúng một lần, sau tất cả các lời gọi khác. Link được gọi không quá \(1\,000\,000\) lần.
3 18 \(N \le 20\,000\). CountCritical được gọi không quá \(100\) lần; Link được gọi không quá \(10\,000\) lần.
4 14 \(N \le 100\,000\). Tổng số lần gọi CountCriticalLink không quá \(100\,000\).
5 31 \(N \le 1\,000\,000\). Tổng số lần gọi CountCriticalLink không quá \(1\,000\,000\).

Ví dụ

Ví dụ 1

Input
7 13
-1
1 2
-1
0 5
-1
2 0
-1
3 2
-1
3 5
-1
4 3
-1
Output
7
7
7
7
4
3
2
Note

\(N=7\) vòng, ban đầu chưa nối với nhau. Sau lời gọi cuối cùng, cấu hình thu được như hình dưới đây.

Có hai vòng then chốt. Loại bỏ vòng \(2\) tạo thành các chuỗi \([1]\), \([0,5,3,4]\)\([6]\). Loại bỏ vòng \(3\) tạo thành các chuỗi \([1,2,0,5]\), \([4]\)\([6]\). Loại bỏ bất kỳ vòng nào khác đều không tạo thành tập các chuỗi rời nhau. Chẳng hạn, nếu loại bỏ vòng \(5\), tuy \([6]\) là một chuỗi, các vòng \(0,1,2,3,4\) nối với nhau không tạo thành chuỗi.

Lời gọi Giá trị trả về
Init(7)
CountCritical() \(7\)
Link(1, 2)
CountCritical() \(7\)
Link(0, 5)
CountCritical() \(7\)
Link(2, 0)
CountCritical() \(7\)
Link(3, 2)
CountCritical() \(4\)
Link(3, 5)
CountCritical() \(3\)
Link(4, 3)
CountCritical() \(2\)

Tệp

Bình luận

Mới nhất
Tải bình luận...

Không có bình luận nào.

Kỳ thi: