You are on page 1of 2

SỞ GD&ĐT LÀO CAI KỲ THI CHỌN ĐỘI TUYỂN HỌC SINH GIỎI THPT QUỐC

GIA
NĂM 2021 (Vòng 1)
ĐỀ CHÍNH THỨC
Hướng dẫn chấm - MÔN: Tin học
( Hướng dẫn chấm gồm 02 trang )

Cách chấm: Copy bài thí sinh vào chương trình chấm tự động THEMIS có sẵn trong
đĩa CD, chạy chương trình chấm.
- Chú ý kiểm tra những bài luôn cho một kết quả với cả bộ test và những bài bị 0 điểm.
Phương án làm test:
Bài 1: Chia dư – 20 tests – 7 điểm
 30% số test tương ứng 30% số điểm có
 30% số test tương ứng 30% số điểm có
 40% số test còn lại tương ứng 40% số điểm có .

Bài 2: Truy vấn trên đồ thị – 20 tests – 7 điểm

 30% tổng số test có


 30% tổng số test tiếp theo có và tất cả các truy vấn là loại 1.
 40% tổng số test còn lại không có ràng buộc gì thêm.

Bài 3: Bộ ba số - 20 tests – 6 điểm


- Có 40 số test với .
- Có 30% số test với
- Có 30% số test với
Giải thuật tham khảo:
Bài 1: Chia dư (7 điểm)
 Sub 1: Duyệt tất cả các cặp

 Sub 2: Đánh dấu trùng lặp, duyệt trên không gian


 Sub 3: Với mỗi số , thực hiện đánh dấu bội của (trừ 1). Quy hoạch động từ
cuối về tạo bảng đáp số.

Bài 2: Truy vấn trên đồ thị (7 điểm)


 Sub 1: Dùng thuật toán Dijkstra, tính độ dài đường đi ngắn ngất giữa hai đỉnh.
Từ mảng trace tính đỉnh thứ k trên đường đi giữa hai đỉnh. Độ phức tạp O(Qn2).
 Sub 2: Không có truy vấn loại 2. Dùng Dijkstra Heap. Độ phức tạp O(Qnlogn).
 Sub 3: Dùng LCA+ QHĐ trên cây: Với mỗi truy vấn giữa hai đỉnh u, v:
Gọi w=LCA(u,v);

1/2
QHĐ trên cây : tính D[i]: độ dài đường đi ngắn nhất từ 1 đến i
Level[i]: level của đỉnh I với gốc là đỉnh 1
Truy vấn loại 1: ĐS= d[u]+d[v]-2*d[w].
Truy vấn loại 2: RMQ: ĐS= Cha(v, 2level[w]+k-level[u]-1) Với cha(v,k) là hàm tìm tổ
tiên thứ k của v.
Độ phức tạp: O(Qnlogn).
Bài 3: Bộ ba số- 6 điểm
Không mất tổng quát ta có thể coi 1≤ ≤ ("nén" mảng a vào trong đoạn [1,n]).
 Subtask 1: Thuật toán thông thường có độ phức tạp O(Qn 3).
 Subtask 2: Về tử tưởng, ta lập trước mảng 2 chiều f[u,v] là số lượng bộ (i,j,k)
thỏa mãn u<i<j<k<v và a[u]>a[i]<a[j]>a[k]<a[v]
Để làm điều này lần lượt với mỗi u cố định (1≤u≤n) và khi v chạy từ u đến n ta duy trì
đồng thời các mảng động sau:
ai[x] = số lượng số có giá trị bằng x với (x<a[u]), bằng 0 khi
x≥a[u] aj[x] = số lượng chỉ số i mà a[u]>a[i]<x ak[x] = số
lượng bộ chỉ số u<i<j mà a[u]>a[i]<a[j]>x.
Khi đó f[u,v]=ak[1]+ak[2]+...+ak[a[v]-1]
Mảng aj tính qua ai và mảng ak tính qua aj. Tham khảo đoạn code sau:
for(u=1;u≤n;++u) {
// reset 0 cho ai, aj, ak for(v=u;v≤n;++v) {
x=a[v]; f[u,v]=0; for(w=1;w<x;++w)
f[u,v] += ak[w]; if (x<a[u]) ai[x]++;
for(w=1;w<x;++w) aj[x] += ai[w];
for(w=x+1;w≤n;++w) ak[x] += aj[w];
}}
 Độ phức tạp khi tính mảng f là O(n3). Sau đó thời gian trả lời cho mỗi truy vấn là
O(1) Subtask 3: Nâng cấp từ subtask 2 bằng cách sử dụng BIT tổng để quản lý
các mảng động ai, aj, ak ở trên:
for(u=1;u≤n;++u) {
// reset 0 cho bit_i, bit_j, bit_k
for(v=u;v≤n;++v) { x=a[v];
f[u,v]=get_k(x-1); if (x<a[u])
update_i(x,1); update_j(x,get_i(x-1));
update_k(x,get_j(n)-get_j(x));
}
}
Độ phức tạp thuật toán giảm xuống còn O(n2logn+Q)
Chú ý: Chương trình mẫu và bộ test có trong đĩa CD.
--------Hết---------

2/2

You might also like