Lợi ích trong phương pháp sử dụng interval tree là với một số đoạn con ta có thể lấy trực tiếp được thông tin trong đoạn con đó mà không phải đi lấy thông tin trong từng phần tử nhỏ tro[r]
(1)TRƯỜNG TRUNG HỌC PHỔ THÔNG CHUYÊN VĨNH PHÚC
Chuyên đề
Một số cấu trúc liệu nâng cao
Người thực hiện: Vũ Mạnh Hà
Tổ: Toán – Tin học
Số điện thoại : 0987 617 833
Email: hatincvp@vinhphuc.edu.vn
(2)Mục lục
INTERVAL TREE
ĐỊNH NGHĨA, CÁC THAO TÁC CƠ BẢN
VÍ DỤ 1.ỨNG DỤNG INTERVAL TREE CƠ BẢN
VÍ DỤ 2.POSTERS –AMPPZ2001
VÍ DỤ MARS MAP – BALTIC OI 2001
VÍ DỤ MATRIX SUM - AL-KHAWARIZM 2006
BÀI TẬP
BINARY INDEXED TREE 10
ĐỊNH NGHĨA, CÁC THAO TÁC CƠ BẢN 10
BINARY INDEXED TREE HAI CHIỀU 11
BÀI TẬP 12
HEAP 14
TÍNH CHẤT HEAP, DUY TRÌ TÍNH CHẤT HEAP 14
VÍ DỤ MEDIAN (PHẦN TỬ TRUNG VỊ) 14
VÍ DỤ LAZY PROGRAMMER – NEERC WESTERN SUBREGION QF 2004 15
VÍ DỤ 3.CONNECTION -10THPOI, STAGE II 15
(3)3
Interval Tree
Interval Tree cấu trúc vô hữu dụng, sử dụng nhiều tốn dãy số Ngồi Interval Tree sử dụng số tốn hình học Có thể nói nắm rõ Interval Tree bạn làm nửa số toán dãy số!
Interval Tree có tên gọi xác Segment Tree tên Interval Tree sử dụng nhiều Việt Nam Nếu tìm “Introduction to Algorithms 2nd Edition” bạn thấy cấu trúc mang tên Interval tree với nội dung khác so với trình bày
Ta xem xét toán đơn giản sau để hiểu Interval Tree:
Định nghĩa, thao tác
Bài toán
Cho dãy số ( ) ban đầu Có hai loại thao tác
dãy:
: tăng giá trị phần tử lên đơn vị
: tìm trả tổng giá trị phần tử từ L tới R
Thực ( ) thao tác thuộc hai loại Yêu cầu tương ứng với
mỗi thao tác đưa kết truy vấn Dữ liệu đảm bảo kết phạm vi số nguyên
bit có dấu
Giải thuật
Thuật toán đơn giản cho toán là: với thao tác ta tăng giá trị với
mỗi thao tác dùng vòng lặp tính lại tổng số đoạn Độ phức tạp
tính tốn ( ) chạy với test lớn
Vậy làm cách để cải tiến thuật toán? Ta dùng Interval Tree để làm giảm độ phức tạp
của phép lấy tổng Nếu làm trên, thao tác thực ( ), dùng
Interval Tree độ phức tạp cịn ( ), cách tính trước số đoạn nhỏ
đoạn [ ] cần tính tính tổng đoạn [ ] cần tính tổng đoạn nhỏ nằm
Cấu trúc Interval sử dụng sau:
Gốc nút quản lý (lưu tổng) đoạn khoảng từ
Xét nút quản lý đoạn [ ]
o Nếu nút khơng có nút
o Nếu , nút có hai nút con: nút trái quản lý đoạn [ ], nút phải
quản lý đoạn [ ],
Khi thao tác đoạn [ ] viết đơn giản sau:
GET(U,V,L,R) //lấy tổng đoạn [U, V], xét đoạn [L, R]
1 if (V<L) or (U>R) return 0; //ngoài đoạn [U, V]
2 if (U>L) and (V<R) return A[L R]; //trong đoạn [U, V]
3 return GET(U, V, L, M) + GET(U, V, M+1, R); //giao đoạn [U, V]
(4)4
Dễ thấy số lần thực đệ quy nhỏ hàm gọi tiếp [ ]
giao không hoàn toàn nằm [ ] Như thao tác thay thực O(N)
nay thực ( )
Xét tiếp thao tác Rõ ràng thao tác INC không đơn giản cập nhật lại phần tử
trước mà ta phải điều chỉnh Interval Tree cho trì tính chất mô tả
Để cập nhật lại Interval Tree với thao tác tăng giá trị phần tử ta phải tăng lượng
cho giá trị nút mà đoạn quản lý chứa
Hàm viết sau:
INC(i, delta, L, R) //xét nút [L, R] , cần tăng a_i lên delta đơn vị
1 if (L>i) or (R<i) return // không chứa a_i
2 A[L R] += delta // nút có chứa a_i
3 INC(i, delta, L, M) // trái
4 INC(i, delta, M+1, R) // phải
Độ phức tạp thao tác ( ) với lí tương tự
Như độ phức tạp thao tác tăng từ ( ) lên ( ) độ phức tạp tổng
cộng cho truy vấn lại ( ) nhanh hẳn so với thuật toán thơ sơ ban đầu
Qua ví dụ trên, hiểu qua phần cấu trúc ý nghĩa sử dụng Interval tree: gốc
nút lưu tồn thơng tin (mà ví dụ tổng) đoạn [ ], từ gốc thông tin nút
chia nhỏ quản lý hai nút trái phải nút lưu thơng tin phần tử Lợi ích phương pháp sử dụng interval tree với số đoạn ta lấy trực tiếp thơng tin đoạn mà khơng phải lấy thông tin phần tử nhỏ
đoạn, việc giúp giảm độ phức tạp thao tác từ ( ) xuống ( )
Tư tưởng Interval tree dùng “chia để trị”: “chia” đoạn lớn thành đoạn nhỏ để “trị” nhanh chóng
Một câu hỏi khác đặt cách tổ chức lưu trữ cây, ta bỏ đoạn để lưu
đoạn [ ] Câu trả lời ta dùng mảng chiều để lưu trữ
đoạn theo mơ hình lưu trữ nhị phân đầy đủ Data for Interval Tree
1 Nút gốc quản lý [1, N], lưu trữ Tree[1] Nếu nút i quản lí [L, R] (L<R)
nút 2i lưu đoạn [L, M] nút 2i+1 lưu đoạn [M+1, R]
Dễ chứng minh độ cao không vượt ⌈ ⌉ Như nhớ dùng cho
( ⌈ ⌉) Trong thực tế khai báo mảng cỡ đủ (tất nhiên dùng danh sách động để lưu cây, cách lưu trữ nút lại tốn nhớ cho liên kết không tiện lợi việc duyệt cây)
Nhược điểm cách lưu trữ mảng chiều tĩnh ta biết đoạn [ ] có
được lưu trọn nút khơng có nút nút Việc định vị đoạn
bắt buộc phải trải qua trình duyệt độ phức tạp ( ) từ gốc xuống
(5)5 Từ sau ta gọi chung thao tác sửa Interval thao tác UPDATE, thao tác lấy thông tin từ thao tác GET
Ứng dụng Interval đa dạng, phong phú Sau ta tìm hiểu số ứng dụng hay gặp Mỗi ví dụ mơ tả cách sử dụng interval tree tương đối khác thường gặp giải tốn
Ví dụ Ứng dụng interval tree
a Cho dãy số, có số yêu cầu thuộc hai loại thay đổi (tăng/gán lại) giá trị phần tử
hoặc tìm min, max đoạn liên tiếp dãy số: nút interval tree lưu giá trị min/max đoạn mà quản lý
b Cho dãy số, có số yêu cầu thuộc hai loại: thay đổi giá trị phần tử tìm
tổng số phần tử liên tiếp dãy Bài toán tương tự ví dụ
Ví dụ Posters – AMPPZ 2001
Có poster chiều cao Theo thứ tự poster dán lên đoạn tường có
chiều cao Đoạn tường xây viên gạch , đánh số từ trái sang phải
Các poster phủ đoạn liên tiếp từ viên gạch tới viên gạch , poster dán
sau phủ lên poster dán trước Vì vậy, sau dán xong poster có
những poster khơng thể nhìn thấy
Yêu cầu: đếm số poster khác nhìn thấy từ ngồi vào
Input: Dịng đầu ghi số poster Trong dòng dòng chứa số đầu
trái đầu phải poster thứ
Output: số ngun số poster nhìn thấy Giới hạn:
Hướng dẫn
Bài tốn phát biểu lại sau: cho dãy số phần tử, có số thao tác tô màu phần
tử dãy số Sau kết thúc chuỗi thao tác đếm số màu khác dãy số
Với nhỏ, ta cần lưu lại màu phần tử sau xem có màu khác
là Nhưng tốn này, lên tới giá trị Do đó, ta phải làm nhỏ lại giá trị
này Nhận xét với hai mà chúng khơng có đầu mút poster chắn màu sắc chúng giống Từ ta thực trộn tất đầu mút đoạn, xếp
tăng dần chúng Thay phải xét tất ( ô) ta cần xét ô đầu mút đoạn,
số lượng không vượt q số, hồn tồn lưu trữ Phương pháp ta
vừa áp dụng gọi phương pháp “rời rạc hoá”, ứng dụng hiệu nhiều toán khác nhau, sử dụng cấu trúc liệu đặc biệt Ý nghĩa chủ yếu với đoạn lớn phần tử giống hệt nhau, không cần xét phần tử mà xét phần tử đại diện Sau bạn cịn gặp nhiều tốn sử dụng phương pháp
Trở lại với toán chúng ta, phải sửa đổi màu phần tử đoạn liên tiếp
Với giới hạn cịn 80000 ta khơng thể làm thơ được, mà dùng interval tree Vì cuối
(6)6
1 Tại nút lưu màu chung phần tử quản lý, khởi tạo màu Chính xác
mỗi nút lưu màu cuối mà sửa, kèm theo thời gian sửa thành màu Q trình sửa màu diễn bình thường kết hợp thêm cập nhật thời gian Màu phần tử màu nút quản lý (màu cập nhật muộn nhất) Dễ thấy giá trị màu phần tử xét Để lấy màu ta cần từ gốc tới nút chứa phần tử chọn màu có thời gian lớn
2 Cây Interval lưu khơng xác màu nút mà lưu cách gần Một nút
lưu màu màu chung tất phần tử quản lý, ngược lại lưu giá trị đặc
biệt để đánh dấu ( ) Ta kết hợp trình sửa lại màu cho phần tử vào
trong trình cập nhật lấy giá trị phần tử Trong trình cập nhật, xét tới nút thuộc đoạn tơ màu gán ln giá trị nút màu kết
thúc (tương tự bình thường), nút cha nút gán giá trị (do màu
các nút khơng cịn giống nhau) Trong trình lấy giá trị phần tử, nút cha mang giá trị dương nút mang giá trị nút cha thay giá trị thời nó, cập nhật lại màu cần diễn trước xét tới nút nút
Hai cách lưu đơn giản Cách dễ hiểu dễ cài đặt cách thứ hai cần hiểu rõ chất tư mạch lạc, không dễ nhầm lẫn giá trị nút Cách thứ hai cịn có
tên gọi cách update lười, chi phí tính tốn cách nhỏ cách đầu nhiều Tương tự
hãy ứng dụng interval vào trường hợp tăng/giảm giá trị tính tổng số đoạn liên tiếp dãy số
Ví dụ Mars map – Baltic OI 2001
Trên mặt phẳng toạ độ có hình chữ nhật, có toạ độ đỉnh phạm vi Tính
diện tích phần mặt phẳng mà điểm bị phủ hình chữ nhật
Input: dịng ghi số , dòng dòng ghi hai cặp số toạ độ
đỉnh trái phải hình chữ nhật
Output: số nguyên tổng diện tích phần mặt phẳng bị phủ hình chữ nhật
Giới hạn:
Hướng dẫn
Ta có hai nhận xét:
Vì toạ độ nguyên, ta chia mặt phẳng thành lưới vng diện tích phần
bị phủ HCN số vng thuộc HCN Như ta cần đếm với cột dọc rộng đơn vị có ô vuông
Số ô bị phủ cột thay đổi HCN phủ thay đổi Do hai cột
khơng có thay đổi HCN phủ lên chúng số vng bị phủ hai cột
Từ hai nhận xét ta tới thuật tốn sau:
Sắp xếp số vị trí cạnh thẳng đứng HCN theo chiều tăng dần, cột
(7)7
Xét cột từ trái sang phải, lần gặp HCN (gặp cạnh trái nó) thêm
đoạn mà phủ cột tương ứng, cạnh dọc phải HCN loại bỏ đoạn mà phủ Mỗi lần xét cột đếm số lượng bị phủ cột
Ta dùng interval tree cho q trình Bài tốn phát biểu lại sau:
Cho dãy số có số, có số thao tác tăng giảm số phần tử liên tiếp dãy lên đơn
vị, sau thao tác hỏi dãy số có số lớn Với giá trị max toạ độ giá trị
lên tới , giá trị lớn khó khăn lưu trữ Nhưng ta
có thể áp dụng phương pháp rời rạc hoá đoạn liên tiếp giống Khi lớn
bằng số HCN, tức mà thơi, tốn lúc khác chút: phần tử kèm
giá trị, tính tổng giá trị phần tử lớn
Với cách phát biểu toán trở nên gần gũi dễ dàng giải nhiều Chỉ cần lưu kèm nút interval số lượng phần tử dương quản lý
Ta thấy sức mạnh Interval tree xử lý toán dãy số Vậy với bảng số sao? Nếu coi dãy số đoạn thẳng (một chiều) bảng số coi HCN (hai chiều) Như hồn tồn dùng Interval Tree theo cách để xử lý bảng số Cây Interval Tree thường gọi Interval Tree 2D – Cây interval tree chiều Nếu Interval Tree có cách biểu diễn thơng dụng dùng hầu hết toán dùng cấu trúc mơ tả trên, lại có tới hai cách hoàn toàn khác để hiểu biểu diễn Interval Tree 2D Xét ví dụ:
Ví dụ Matrix sum - Al-Khawarizm 2006
Cho ma trận Ban đầu tất ô ma trận mang giá trị Các dòng đánh số từ tới
từ xuống dưới, cột đánh số từ tới từ trái qua phải Có trình xử lý gồm
thao tác ma trận:
1 : gán giá trị ô ( ) giá trị
2 : tính in tổng giá trị ô HCN ô trái ( ) phải
( )
3 END : kết thúc chương trình
Yêu cầu: viết chương trình đọc vào lệnh trình xử lý, tính đưa kết thao tác SUM
Giới hạn: Giải thuật
Kí hiệu ( ) hình chữ nhật giới hạn hàng cột
Cách 1: Quản lý song song chiều:
Với Interval tree đoạn chia đôi chia đôi dần Sử dụng tư tưởng Interval Tree 2D ta chia đơi theo hàng cột Mỗi nút interval tree quản lý bảng HCN nhỏ
trong bảng HCN ban đầu chia thành nút Hay nói cách khác nút ( ) có
thể có tối đa nút ( ) ( ) ( ) (
) với
(8)8 Áp dụng vào toán ta lưu nút tổng giá trị mà HCN quản lý Các hàm GET UPDATE viết hồn tồn tương tự hàm với Interval tree, khác điểm từ nút
gọi tới nút thay Độ phức tạp thuật tốn cho thao tác trở thành ( )
Cách 2: Quản lý theo chiều:
Với bảng số ta dùng interval tree quản lý hàng riêng rẽ (lớp ) Tại nút ( )
cây lưu hàng lưu tổng ô từ tới hàng Vì hàng có cột nên số nút
cây Giả sử có nút Ta sử dụng lớp gồm
cây interval nữa, quản lý nút: thứ quản lý nút thứ interval
trước Vậy giá trị HCN truy xuất nào? Với ( ), đầu
tiên ta tìm nút thuộc đoạn ( ) thuộc lớp Với nút truy xuất liệu
tương ứng thuộc đoạn từ tới Quá trình UPDATE liệu tương tự Độ
phức tạp thuật toán dạng ( ) cho thao tác UPDATE GET
Bài tập
1 CUTSEQ – Marathon 06-07
Cho số nguyên dãy số nguyên Nhiệm vụ bạn phải cắt dãy số thành
một số dãy số (giữ nguyên thứ tự) thỏa mãn:
Tổng dãy số không lớn số nguyên
Tổng số lớn dãy nhỏ
Input: Dòng đầu gồm số nguyên ; dòng thứ hai gồm số nguyên
Output: số nguyên tổng số lớn dãy số Nếu khơng có cách cắt
thỏa mãn hai điều kiện trên, in
Giới hạn:
2 The BUS – POI 2004
Cho lưới vng số kích thước Tại nút (giao hàng cột) lưới có giá trị ,
các nút khác giá trị Một đường từ ô ( ) tới ô ( ) lưới đường thoả mãn
các điều kiện sau:
Đi theo cạnh lưới ô vuông, không theo đường chéo
Chỉ từ nút ( ) tới nút ( ) nút ( )
Giá trị đường tổng giá trị nút thuộc đường Tìm đường có giá trị lớn đưa file output giá trị
Input: dòng ghi số nguyên dòng dòng ghi số ý nghĩa
là nút ( ) có giá trị
Output: dịng ghi kết tìm Giới hạn:
3 POINTS and RECTANGES
Trong mặt phẳng toạ độ cho hình chữ nhật điểm Một điểm gọi thuộc HCN
nếu điểm nằm phần mặt phẳng giới hạn HCN
(9)9 Input: Dòng đầu ghi số nguyên ; dòng dòng ghi số nguyên mô
tả HCN với đỉnh trái ( ) phải ( ); dòng cuối ghi toạ độ điểm
cho
Output: ghi điểm thoả mãn (thứ tự bất kì) Giới hạn:
4 Greatest sub sequence:
Cho dãy số gồm phần tử ( | | ) Hàm đoạn [ ] định
nghĩa sau: ( ) )
(10)10
Binary Indexed Tree
Định nghĩa, thao tác
Trong toán dãy số, cấu trúc liệu thường sử dụng thay cho interval tree Binary Indexed Tree Mặc dù vậy, cấu trúc Binary Indexed Tree lại khác hoàn toàn với Interval Tree Tuy gọi “tree” Binary Indexed Tree lại giống rừng - gồm nhiều giống Cấu trúc Binary Indexed Tree định nghĩa đệ quy sau:
Binary Tree
1 i lẻ: cha[i]=i+1;
2 i chẵn: cha[i]=cha[i div 2]*2;
Như [ ] không phụ thuộc vào số nút mà phụ thuộc trực tiếp vào giá trị Lưu ý với
cây nút với , [ ] coi [ ] không tồn
Cũng interval tree, thông tin lưu nút binary indexed tree thông tin tất nút (các phần tử nút bị quản lý)
Thơng tin nút tích luỹ lên Nhưng thay số nút nhiều
interval, ta cần dùng mảng ( ) để lưu trữ tồn thơng tin liệu binary indexed
tree Cải thiện nhớ giúp ích đáng kể mơi trường bị hạn chế nhớ Thông thường sử dụng binary indexed tree sử dụng hai thao tác sau:
1 Từ nút truy xuất tới nút [ ]
2 Từ nút truy xuất tới nút lớn nhất, nhỏ không , gọi
Nếu vào định nghĩa [ ] ta xác định nút ( ) ta có cách
hiệu nhiều:
[ ] ( ( )) ( )
( ( )) – ( ) ( )
Các phép toán dùng phép toán bit, thực nhanh nhiều so với
phép tốn … Đây điểm mạnh tốc độ binary indexed tree so với interval
tree
Việc truy xuất tới [ ] để cập nhật thông tin lưu trữ ngược lại, truy xuất đến
dùng để lấy thông tin Dựa vào thao tác ta dễ dàng lấy thơng tin tổng hợp từ tất
cả nút từ tới : {info[ ]} [ ]+{info[ ]}, [ ] thông tin lưu trữ ,
dấu biểu cho hợp thơng tin, đơi phép nhân
Độ phức tạp lần lấy thông tin không vượt
Giới hạn Binary Indexed Tree thao tác thứ hai có tác dụng lấy thơng tin nửa
khoảng ( ] mà không cho lấy thông tin tổng hợp đoạn [ ] ( )
trong trường hợp tổng quát Do tác dụng Binary indexed Tree bị hạn chế so với Interval tree Binary Indexed Tree thực tuyệt vời trường hợp sau:
Thơng tin lưu trữ phải có tính tích luỹ, tổng, tích, giá trị min, max
(11)11 Lưu ý: Vẫn lấy thơng tin đoạn [ ] trường hợp cịn lại với độ
phức tạp thuật toán cao hơn, cỡ ( ) theo cách sau:
Tonghop(i,j)
1 j’ = j and (j-1);
2 if (j’+1>=i) return T[j]+tonghop(i,j’) else return T’[j]+tonghop(i,j-1)
Trong [ ] thơng tin “của” Đơi cách làm thay cho cách làm Interval tree
với độ phức tạp ( ), thời gian chạy không lâu code ngắn đơn
giản
Ta kết hợp “Rời rạc hoá” sử dụng Binary Indexed Tree mở rộng Binary Indexed Tree thành chiều Cách sử dụng “rời rạc hố” khơng cịn xa lạ nữa, xin nói thêm Binary Indexed Tree 2D
Binary indexed tree hai chiều
Bài toán
Bảng số nguyên, cài đặt hàm thực hai loại truy vấn:
1 Thay đổi giá trị ô bảng
2 Tính tổng phần tử hình chữ nhật bảng
Giải thuật
Chia bảng thành dãy con, dãy hàng Dùng binary indexed tree để lưu
dãy Đây tập ( ) Giá trị nút tổng số quản lý Sau sử
dụng binary indexed tree (tập ) để quản lý Cây thứ tập
quản lý tất nút thứ thuộc tập
Khi đó, gặp thao tác thay đổi, q trình update xảy tập tới tập
Giả sử update vị trí ( ):
Update_BIT2D(u,v)
1 Cập nhật nút V thứ U tập T1
2 Cập nhật thứ V tập T2, nút bắt đầu nút U t = v + v and (-v) // t=cha[v]
4 Update_BIT2D(u,t)
Quá trình thực ( ) có thủ tục gọi update tập
Thao tác tính giá trị HCN có trái ( ) phải ( ) thực (
) sau: Get2D(u,v)
1 ret = giá trị nút U thứ V, tập T2 v = v - v and (-v)
3 return ret + GET_BIT2D(u,v) Như vậy:
( ) ( ) ( ) ( ) ( )
Trong toán sử dụng để lưu giá trị với ý nghĩa khác ta cần sửa chút hàm GET (bước 1) hàm cập nhật thuộc tập T2
(12)12 Qua ý ta thấy đặc điểm Binary Indexed Tree Dựa vào thấy: tốn làm Binary Indexed Tree làm Interval Tree Để hiểu rõ cấu trúc quan trọng ghi nhớ công thức nêu, sau số tập ứng dụng Sau làm Binary Indexed Tree, bạn thử làm với Interval Tree để so sánh tốc độ độ phức tạp thuật toán
Bài tập
1 DNT – Marathon 05-06 (IOIcamp.net)
Cho dãy số Một nghịch cặp số cho:
Yêu cầu: đếm số lượng nghịch dãy số cho
Input: Dòng ghi số số lượng số dãy số dòng ghi giá trị số thuộc dãy
Output: số số lượng nghịch đếm Giới hạn:
2 Mobile Phones - IOI 2001
Giả thiết hệ thứ điện thoại di động (mobile phone) có trạm làm việc nằm vùng Tampere hoạt động sau: Vùng hoạt động chia theo lưới ô vuông Các ô vuông
tạo thành ma trận với hàng cột đánh số Mỗi ô vuông chứa
trạm làm việc Số lượng điện thoại hoạt động (active) ô vuông bị thay đổi người sử dụng điện thoại di chuyển từ ô sang ô khác điện thoại chuyển chế độ bật/tắt Theo thời gian, trạm làm việc báo cáo thay đổi số lượng điện thoại di động hoạt động khu vực kiểm sốt
Hãy viết chương trình nhận báo cáo trả lời truy vấn tổng số điện thoại di động hoạt động vùng khơng gian hình vng cho trước
Input:
Dòng ghi S kích thước bảng
Trong số dòng sau, dòng thuộc hai dạng:
: tăng thêm lượng (có thể âm) vào số điện thoại hoạt động ô vuông ( )
: yêu cầu cho biết tổng số lượng máy điện thoai hoạt động vùng HCN góc
trái ( ) phải ( )
3 Team Selection – Balkan OI 2004
Trong thi lớn có thí sinh tham gia Cuộc thi gồm phần thi nhỏ Tất thí sinh
đều tham gia có điểm số phần thi này, điểm số thí sinh khác phần thi khác Sau thi kết thúc, BTC muốn tìm thí sinh giỏi Thí sinh giỏi thí sinh khơng thí sinh khác (Thí sinh A coi giỏi thí sinh B điểm số phần thi cao thí sinh B)
Yêu cầu: cho biết điểm phần thi N thí sinh, đếm số thí sinh coi giỏi
Input: dịng ghi số N số thí sinh tham dự N dòng dòng thứ ghi số nguyên
là điểm môn thi thí sinh thứ
(13)(14)14
Heap
Tính chất heap, trì tính chất heap
Heap cấu trúc liệu hữu dụng vào bậc lập trình thuật tốn, khía cạnh ý nghĩa lý thuyết hiệu thực hành Heap chủ yếu dùng để cài đặt Priority Queue (hàng đợi có độ ưu tiên) Cấu trúc heap có ba loại chính: binarry heap (heap nhị phân), binomial heap (heap nhị thức) Fibonaci heap Ở trình bày binarry heap:
Binary heap thực chất nhị phân cân thoả mãn điều kiện sau:
Mỗi nút có khơng q nút
Nút cha nút lớn (tốt) nhất, nút ln có giá trị nhỏ nút cha
Điều kiện quan hệ nhỏ nút so với nút cha quy định trước tuỳ theo tốn, khơng thiết phải nhỏ theo nghĩa số học
Mặc dù mô tả binary heap lưu trữ mảng chiều, nút gốc
nút 1, nút nút nút Điều làm cho độ cao nút nhỏ
hoặc ⌈ ⌉
Ứng dụng chủ yếu heap tìm min, max (độ ưu tiên cao nhất) tập hợp động, nghĩa tập thay đổi, thêm, bớt phần tử
Các thao tác thường dùng xử lý heap:
: nút lớn cha di chuyển lên
: nút nhỏ di chuyển xuống
: đưa phần tử vào heap cách thêm nút vào nút
: loại phần tử khỏi heap cách chuyển xuống cuối heap loại bỏ, sau
chỉnh sửa lại heap cho thoả mãn tính chất heap
Điểm đặc biệt lưu ý trình đưa phần tử vị trí khỏi heap phải thực
hiện trình để đảm bảo tính chất heap
Heap sử dụng thuật toán Dijkstra, Kruskal, Heap Sort nh ằm giảm độ phức tạp thuật tốn Heap cịn sử dụng toán dãy số, QHĐ, đồ thị, Các ví dụ cho thấy phần đa dạng linh hoạt sử dụng Heap Để thuận tiện ta gọi heap-max heap mà giá trị nút cha lớn giá trị nút (phần tử đạt max gốc heap) heap-min heap mà giá trị nút cha nhỏ giá trị nút (phần tử đạt gốc heap)
Ví dụ Median (Phần tử trung vị)
Phần tử trung vị tập phần tử phần tử có giá trị đứng thứ với lẻ
với chẵn
Cho tập hợp ban đầu rỗng Trong file input có ( ) thao tác thuộc hai loại:
1 : đưa phần tử giá trị vào
2 : xác định giá trị phần tử trung vị tập hợp (nếu chẵn trả giá trị) Yêu cầu: viết chương trình đưa file out tương ứng
(15)15 Output: tương ứng với thao tác MEDIAN trả (hoặc 2) giá trị tương ứng
Giải thuật
Dùng hai heap, heap ( ) lưu phần tử từ thứ tới heap lại ( ) lưu
phần tử từ tới N sau sort lại tập thành tăng dần heap-max
heap-min Như phần tử trung vị gốc ( lẻ) gốc ( chẵn) Thao tác
có độ phức tạp ( ) Cịn thao tác làm ( ) sau:
Nếu đưa vào nhỏ [ ] đưa vào ngược lại đưa vào Số phần tử
của tập tăng lên
Nếu có nhiều (ít hơn) phần tử phần tử từ ( ) đưa vào heap
( )
Sau trình đảm bảo theo định nghĩa ban đầu Bài toán giải
quyết với độ phức tạp ( )
Ví dụ Lazy programmer – NEERC western subregion QF 2004
Có cơng việc, việc buộc phải hồn thành trước thời gian [ ] (thời gian 0) công
việc giao cho programmer lười biếng Xét cơng việc , bình thường programmer
làm xong [ ] thời gian trả thêm $ làm xong
[ ] [ ] (nếu [ ] [ ] làm xong tức khắc) Tất nhiên
[ ] [ ] Tiền trả thêm với công việc độc lập với
Yêu cầu: với mảng D[], B[] A[] cho trước tìm số tiền phải trả thêm cho programmer để công việc hồn thành hạn
Input: Dịng ghi số Dòng thứ dòng dòng ghi số
[ ] [ ] [ ]
Output: tổng số tiền nhỏ phải trả thêm (chính xác tới hai chữ số phần thập phân) Giới hạn: [ ] [ ] [ ]
Giải thuật
Nhận thấy xét tới thời điểm cơng việc có [ ] buộc phải làm xong
Nên ta xếp công việc tăng dần theo thời gian deadline [] Ta phải trả thêm tiền
cho programmer tới công việc thứ tổng thời gian [] từ tới lớn [ ] Lúc ta
cần chọn số công việc trước cơng việc để trả thêm tiền cho tiết kiệm thời
gian làm Dĩ nhiên cơng việc chọn phải có [] cao tốt
Từ ta có thuật giải có độ phức tập ( ) dựa heap-max chứa công việc
đã làm ưu tiên theo []
Ví dụ Connection - 10
thPOI, stage II
Cho đồ thị đơn, có hướng gồm đỉnh cung Một đường từ tới đường đi qua
cung đồ thị, lặp lại cung đỉnh qua nhiều lần Cần tìm độ dài đường ngắn
thứ từ tới cho trước
(16)16 Input: Dòng ghi số Dòng thứ dòng dòng ghi số mô
tả cung đồ thị cung từ tới có độ dài Dịng thứ chứa số câu hỏi Trong T
dòng dịng ghi số mơ tả câu hỏi Các số input số nguyên
Output: dòng, dòng thứ câu trả lời cho câu hỏi thứ Nếu từ tới có đường (khác
nhau) trả giá trị
Giới hạn: Giải thuật
Rõ ràng ta phải tính trước đường ngắn từ tới Làm để làm điều
đó? Với đỉnh dùng thuật tốn DIJKSTRA để tính đường ngắn tới tất đỉnh
còn lại Giả sử xét tới đỉnh , [ ] đường ngắn thứ từ tới Với tính
[ ] với từ tới (tính xong giá trị cũ tính tới giá trị mới), [ ]
giá trị tính (khởi tạo [ ] ) Sau bước thuật toán:
CONNECTION(U)
1 Với v=1 N, v<>u: Tìm v: C[u,v,k0[v]] đạt GTNN, min=C[u,v,k0[v]] Xác nhận C[u,v,k0[v]] đường cần tìm, K0[v]++
3 Với v’ mà có đường từ v tới v’ (dài L) tạo thêm đường từ u tới v’ độ dài L’=min+L, cập nhật đường từ U tới V
Các bước thuật tốn Dijkstra thơng thường Vì giá trị xét lần nên
với đường từ tới ta phải lưu trữ lại, nhưng, cần tìm đường ngắn
nhất nên ta cần lưu trữ lại [ ] đường
Bước viết rõ ràng sau: 3.Update(v’,L’)
3.1 Tìm đường dài đường lưu 3.2 Nếu đường ngắn L’ kết thúc
3.3 Loại bỏ đường 3.4 Lưu trữ đường dài L
Tập đường lưu trữ với đỉnh tập động, ta dùng heap-max để lưu trữ tập
đường Lúc bước [ [ ]] phải chọn tập Có thể kết hợp
một heap-min để tìm nhanh [ [ ]] Cách cài đặt phức tạp đòi hỏi phải hiểu rõ
heap Một cách khác đơn giản cập nhật [ [ ]] bước tìm đường
mới:
3.Update(v’,L’)
2a Xác nhận , K0[v]++
2b Nếu K0[v]<maxk: Tìm C[u,v,k0[v]]=min(tập lưu trữ đường v’)
4
5 Nếu (L’<C[u,v,k0[v]]) > C[u,v,k0[v]]=L’
Độ phức tạp hàm CONNECTION ( ) Phải gọi lần hàm nên độ phức tạp
của thuật tốn ( ) Lưu ý khơng nên dùng thuật toán Dijkstra kết hợp cấu trúc
heap tốn đồ thị cho đồ thị dày
Nhận xét: toán hay khó ứng dụng heap, điểm quan trọng nhận cách xây dựng đường ngắn từ nhỏ tới lớn ứng dụng heap vào trình
(17)17 1 Lightest language – POI VI, stage III
Cho trước Tập Ak gồm k chữ bảng chữ (2<=k<=26) Mỗi chữ tập Ak có khối lượng cho trước Khối lượng từ tổng khối lượng chữ từ “language” tập Ak tập hữu hạn từ xây dựng chữ tập A, có khối lượng tổng khối lượng từ thuộc Ta nói “language” “prefixless” với cặp từ u,v “language” u khơng tiền tố v (u tiền tố v tồn s cho v=u+s với ‘+’ phép hợp xâu)
u cầu: Tìm khối lượng nhỏ “language” gồm N từ “prefixless” tập Ak cho trước (N<=10000)
Input: Dòng ghi số N K Trong K dòng dòng ghi khối lượng chữ tập Ak, theo thứ tự từ điển “a”
Output: Một dòng ghi khối lượng nhỏ ngơn ngữ thoả điều kiện Ví dụ Input 2 Output 16
(với input trên, ngôn ngữ chọn L={ab,aba,b}
2 Promotion - VII Polish Olympiad In Informatics 2000, stage III
Cho tập hợp A gồm số tự nhiên Ban đầu tập A tập rỗng Trong N ngày, người ta làm công việc sau:
Thêm vào tập A số số tự nhiên
Lưu lại hiệu số lớn số nhỏ tập A
Loại bỏ số lớn nhỏ khỏi tập A
Yêu cầu: cho biết danh sách số thêm vào ngày, tính tổng số lưu lại sau ngày Biết tập A trước bước b ln có số
Input: Dòng ghi số N Trong N dòng tiếp theo, dòng ghi theo định dạng sau: số đầu tiên số lượng số thêm vào, sau giá trị số thêm vào
Output: số tổng số lưu lại Ví dụ
Input:
3 1 10 5
1
Output: 19
Gợi ý: heap-min heap-max tập động, khó toán nằm kĩ cài đặt heap tập Ngồi dùng heap dùng Interval Tree Binary Indexed Tree 3 Birthday – based on IOI 2005
(18)18 số tự nhiên – nghĩa sau xếp lại đứa trẻ p(i) ngồi đứa trẻ p(i-1) đứa trẻ p(i+1), đứa trẻ p(n) ngồi cạnh đứa trẻ p(1) p(n-1) Để xếp lại, đứa trẻ cần di chuyển số bước qua trái qua phải vị trí phù hợp Cha mẹ byteman muốn đứa trẻ di chuyển tốt - tức tổng độ dài di chuyển N đứa trẻ đạt GTNN Tìm giá trị Input: Dịng đầu ghi số N, dòng ghi N số thứ tự bọn trẻ