IOI 2021 - Mutating DNA

Xem PDF



Dạng bài
Ngôn ngữ cho phép
C++
Điểm: 1300 (p) Thời gian: 1.0s Bộ nhớ: 2G Input: bàn phím Output: màn hình

Grace là một nhà sinh học làm việc tại một công ty tin sinh học ở Singapore. Trong công việc của mình, cô phân tích các chuỗi ADN của nhiều sinh vật khác nhau. Một chuỗi ADN được định nghĩa là một xâu gồm các ký tự A, TC. Chú ý rằng trong bài này, các chuỗi ADN không chứa ký tự G.

Một phép đột biến là thao tác hoán đổi hai phần tử của một chuỗi ADN. Ví dụ, một phép đột biến có thể biến ACTA thành AATC bằng cách hoán đổi hai ký tự AC được in đậm.

Khoảng cách đột biến giữa hai chuỗi là số phép đột biến ít nhất cần thực hiện để biến chuỗi này thành chuỗi kia, hoặc bằng \(-1\) nếu không thể biến chuỗi này thành chuỗi kia bằng các phép đột biến.

Grace đang phân tích hai chuỗi ADN \(a\)\(b\), mỗi chuỗi có \(n\) phần tử được đánh chỉ số từ \(0\) đến \(n-1\). Nhiệm vụ của bạn là giúp Grace trả lời \(q\) câu hỏi có dạng: khoảng cách đột biến giữa chuỗi con \(a[x..y]\) và chuỗi con \(b[x..y]\) là bao nhiêu? Ở đây, chuỗi con \(s[x..y]\) của chuỗi ADN \(s\) là dãy các ký tự liên tiếp của \(s\) có chỉ số từ \(x\) đến \(y\), bao gồm cả hai đầu mút. Nói cách khác, \(s[x..y]\) là dãy \(s[x]s[x+1]\ldots s[y]\).

Chi tiết cài đặt

Bạn cần cài đặt các hàm sau:

C++
void init(std::string a, std::string b);
  • a, b: các xâu độ dài \(n\), biểu diễn hai chuỗi ADN cần phân tích.
  • Hàm này được gọi đúng một lần, trước mọi lời gọi tới get_distance.
C++
int get_distance(int x, int y);
  • x, y: chỉ số bắt đầu và kết thúc của các chuỗi con cần phân tích.
  • Hàm cần trả về khoảng cách đột biến giữa \(a[x..y]\)\(b[x..y]\).
  • Hàm này được gọi đúng \(q\) lần.

Dữ liệu vào

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

  • Dòng \(1\): n q.
  • Dòng \(2\): a.
  • Dòng \(3\): b.
  • Dòng \(4+i\) (\(0\le i\le q-1\)): x y cho lời gọi get_distance thứ \(i\).

Dữ liệu ra

Trình chấm mẫu in câu trả lời theo định dạng sau:

  • Dòng \(1+i\) (\(0\le i\le q-1\)): giá trị trả về của lời gọi get_distance thứ \(i\).

Ràng buộc

  • \(1\le n,q\le 100\,000\).
  • \(0\le x\le y\le n-1\).
  • Mỗi ký tự của \(a\)\(b\) là một trong các ký tự A, TC.

Phân nhóm

Nhóm Điểm Ràng buộc bổ sung
1 21 \(y-x\le 2\).
2 22 \(q\le 500\), \(y-x\le 1000\); mỗi ký tự của \(a\)\(b\)A hoặc T.
3 13 Mỗi ký tự của \(a\)\(b\)A hoặc T.
4 28 \(q\le 500\), \(y-x\le 1000\).
5 16 Không có ràng buộc bổ sung.

Ví dụ

Ví dụ 1

Input
6 3
ATACAT
ACTATA
1 3
4 5
3 5
Output
2
1
-1
Note

Xét lời gọi:

init("ATACAT", "ACTATA")

Giả sử trình chấm gọi get_distance(1, 3). Lời gọi này cần trả về khoảng cách đột biến giữa \(a[1..3]\)\(b[1..3]\), tức là hai chuỗi TACCTA. Có thể biến TAC thành CTA bằng \(2\) phép đột biến: \(\mathrm{TAC}\to\mathrm{CAT}\), sau đó \(\mathrm{CAT}\to\mathrm{CTA}\); không thể thực hiện việc biến đổi với ít hơn \(2\) phép đột biến. Vì vậy, lời gọi này cần trả về \(2\).

Giả sử trình chấm gọi get_distance(4, 5). Lời gọi này cần trả về khoảng cách đột biến giữa ATTA. Có thể biến AT thành TA bằng một phép đột biến, và rõ ràng cần ít nhất một phép đột biến. Vì vậy, lời gọi này cần trả về \(1\).

Cuối cùng, giả sử trình chấm gọi get_distance(3, 5). Không thể biến CAT thành ATA bằng bất kỳ dãy phép đột biến nào, nên lời gọi này cần trả về \(-1\).

Nguồn

IOI 2021, Ngày 2 — Mutating DNA (dna).

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: