acm icpc hcmc 2017 editorial - icpcvn.github.io

24
ACM ICPC HCMC 2017 Editorial Overview Tên bài Số AC Độ khó Lời giải nhanh nhất A - Arranging Wine 1 5 Phút 207 sleep 18000 - The University of Tokyo B - Barcode 46 2 Phút 27 sleep 18000 - The University of Tokyo C - Cu Chi Tunnels 124 1 Phút 12 sleep 18000 - The University of Tokyo D - Dropping Ball 5 4 Phút 166 Aizu_Dragon - University of Aizu E - Engaging with Loyal Customers 16 2 Phút 18 Reboom - Peking University F - Famous Pagoda 18 3 Phút 51 Cxiv - Dxiv - The University of Tokyo G - Game of Divisibility 3 3 Phút 163 Cxiv - Dxiv - The University of Tokyo H - Height Preservation 47 2 Phút 59 Reboom - Peking University I - ICPC Awards 147 0 Phút 5 Kizza Manau - Universitas Indonesia J - Joining Network 5 3 Phút 126 unsigned - UET VNU K - K-rotating 5 3 Phút 241 DoWF - Korea University L - Land Inheritance 0 4 N/A Bộ đề được chuẩn bị bởi: Lăng Trung Hiếu Phạm Văn Hạnh Nguyễn Thành Trung - RR Lê Đôn Khuê và 1 số thầy giáo dạy ở các trường đại học, cấp 3 trong cả nước.

Upload: others

Post on 03-Oct-2021

10 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

ACM ICPC HCMC 2017 Editorial Overview

Tecircn bagravei Số AC Độ khoacute Lời giải nhanh nhất

A - Arranging Wine 1 5 Phuacutet 207 sleep 18000 - The University of Tokyo

B - Barcode 46 2 Phuacutet 27 sleep 18000 - The University of Tokyo

C - Cu Chi Tunnels 124 1 Phuacutet 12 sleep 18000 - The University of Tokyo

D - Dropping Ball 5 4 Phuacutet 166 Aizu_Dragon - University of Aizu

E - Engaging with Loyal Customers

16 2 Phuacutet 18 Reboom - Peking University

F - Famous Pagoda 18 3 Phuacutet 51 Cxiv - Dxiv - The University of Tokyo

G - Game of Divisibility 3 3 Phuacutet 163 Cxiv - Dxiv - The University of Tokyo

H - Height Preservation 47 2 Phuacutet 59 Reboom - Peking University

I - ICPC Awards 147 0 Phuacutet 5 Kizza Manau - Universitas Indonesia

J - Joining Network 5 3 Phuacutet 126 unsigned - UET VNU

K - K-rotating 5 3 Phuacutet 241 DoWF - Korea University

L - Land Inheritance 0 4 NA

Bộ đề được chuẩn bị bởi

Lăng Trung Hiếu Phạm Văn Hạnh Nguyễn Thagravenh Trung - RR Lecirc Đocircn Khuecirc vagrave 1 số thầy giaacuteo dạy ở caacutec trường đại học cấp 3 trong cả nước

Lời giải được đoacuteng goacutep bởi Lecirc Quang Tuấn Nguyễn Đinh Quang Minh Phạm Cao Nguyecircn - team VNU - unsigned Nguyễn Diệp Xuacircn Quang - team HCMUS Illuminate Phạm Văn Hạnh Nguyễn Thagravenh Trung - RR Lecirc Đocircn Khuecirc Lăng Trung Hiếu

Nếu coacute thắc mắc về lời giải bạn coacute thể hỏi ở group VNOI Trong caacutec lời giải coacute sử dụng 1 số bagravei viết trecircn VNOI wiki

Sagraveng số nguyecircn tố Tiacutenh nghịch đảo modulo Tối ưu hoaacute QHĐ Kĩ thuật bao lồi Caacutec chủ đề về đồ thị

Caacutec bạn coacute thể nộp thử bagravei ở Kattis Code mẫu httpsgithubcomacmicpc-vietnamacmicpc-vietnamgithubiotreemaster2017regional Bảng xếp hạng cuối cugraveng httpshochiminh17kattiscomstandings

A Arranging Wine (5)

Taacutec giả Lăng Trung Hiếu

Lời giải 1 Phạm Văn Hạnh Thể loại Tổ hợp Inclusion-Exclusion Nhận xeacutet Giả sử ta xếp caacutec thugraveng rượu thagravenh một hagraveng ngang gồm R + W thugraveng rượu sau đoacute xếp caacutec thugraveng rượu liecircn tiếp cugraveng magraveu vagraveo một chồng ta sẽ được một datildey caacutec chồng rượu vang đỏ trắng xen kẽ (mỗi chồng chứa đuacuteng một loại rượu vagrave hai chồng cạnh nhau coacute rượu khaacutec magraveu) Do đoacute bagravei toaacuten coacute thể phaacutet biểu lại như sau

Đếm số datildey nhị phacircn gồm R bit 1 vagrave W bit 0 sao cho coacute khocircng quaacute D bit 1 liecircn tiếp Ta xếp W bit 0 lecircn datildey vagrave lần lượt đặt R bit 1 vagraveo đagraveu datildey cuối datildey hoặc xen giữa caacutec bit 0 Bagravei toaacuten đoacute được chuyển về bagravei toaacuten tổng quaacutet sau đacircy

Đếm số datildey số nguyecircn khocircng acircm coacute vagrave x )( 1 x2 xn sumn

i=1xi = S forall10 le xi le k le i le n

Để giải quyết bagravei toaacuten nagravey ta sử dụng nguyecircn lyacute bao hagravem loại trừ với mục điacutech đưa về bagravei toaacuten dễ giải hơn - bagravei toaacuten khocircng coacute ragraveng buộc Đaacutep số bagravei toaacuten khi đoacute lagrave Phầnxi le k Cnminus1

S+nminus1 chứng minh xin nhường lại cho bạn đọc Bagravei toaacuten sau đacircy cũng coacute lời giải đơn giản lagrave hệ quả của bagravei toaacuten đơn giản phiacutea trecircn Cho

đếm số datildey coacute vagrave 1 Asub 2 n x )( 1 x2 xn sumn

i=1xi = S foralliisin0 le xi A forallik lt xi isin A

Vai trograve của tập hợp A trong datildey trecircn lagrave với mọi ta biết chắc chắn lagrave phần tử xấuiisin A xi Ngược lại nếu coacute thể xấu cũng coacute thể tốt (coacute thể hoặc ta chưax )( i gt k isini A xi xi le k xi gt k

rotilde) Gọi lagrave đaacutep số của bagravei toaacuten trecircn với tập hợp A lagrave tập hợp caacutec phần tử chắc chắn xấu Để(A)f tigravem đaacutep số của bagravei toaacuten ban đầu (tigravem số datildey khocircng chứa phần từ xấu) ta nghĩ tớix )( 1 x2 xn yacute tưởng sau Gọi lagrave đaacutep số của bagravei toaacutenesultr

0 Đầu tiecircn ta giả sử đaacutep số bagravei toaacuten lagrave số datildey magrave caacutec phần tử coacute thể tốt hoặc xấu tugravey yacute Sau đoacute ta tigravem caacutech loại đi những đaacutep aacuten xấu

int result = f(empty) 1 Đầu tiecircn ta sẽ loại bỏ caacutec datildey coacute chiacutenh xaacutec một phần tử xấu nghĩa lagrave

for (int i = 1 i lt= n i++)

result -= f(i)

2 Sau bước vừa rồi ta thấy trong result khocircng chứa caacutec datildey coacute duy nhất một phần tử xấu Tuy nhiecircn những datildey coacute chiacutenh xaacutec hai phần tử xấu vừa bị trừ 2 lần ở bước trecircn nghĩa lagrave đang bị trừ thừa 1 lần necircn giờ phải cộng ngược lại

for (int i = 1 i lt= n i++)

for (int j = i + 1 j lt= n j++)

result += f(i j)

3 Sau bước vừa rồi ta đatilde hoagraven toagraven loại bỏ khỏi result những datildey coacute chiacutenh xaacutec một hoặc hai phần tử xấu Giờ ta muốn loại bỏ khỏi result những datildey coacute chiacutenh xaacutec ba phần tử xấu Hatildey quan saacutet những datildey nagravey đatilde bị tiacutenh bao nhiecircu lần ở result trong ba bước trecircn Ở bước 0 mỗi datildey được cộng 1 lần Ở bước 1 mỗi datildey bị trừ 3 lần (Một datildey coacute ba vị triacute xấu

sẽ được tiacutenh trong ) Tới bước 2 mỗi datildey lại được cộng lại ba lần x y z (x) (y) (z)f f f (Một datildey coacute ba vị triacute xấu sẽ được tiacutenh trong ) Như vậy hiện tại x y z (x ) (y ) (z )f y f z f x mỗi datildey coacute chiacutenh xaacutec ba phần tử xấu hiện đang được tiacutenh 1 lần trong result Cocircng việc của ta bacircy giờ lagrave trừ noacute đi

for (int i = 1 i lt= n i++)

for (int j = i + 1 j lt= n j++)

for (int k = j + 1 k lt= n k++)

result -= f(i j k)

hellip Tiếp tục lập luận tương tự ta đi tới quy tắc tiacutenh sau đacircy Xeacutet mọi tập con A của

Nếu A coacute chẵn phần tử ta cộng thecircm vagraveo result Ngược lại nếu A coacute lẻ phần1 2 n (A)f tử ta trừ đi ở result (A)f

Dễ thấy giaacute trị của chỉ phụ thuộc vagraveo lực lượng của tập hợp A ta kyacute hiệu(A)f với tập hợp A tugravey yacute coacute K phần tử Thuật toaacuten chuẩn của bagravei toaacuten lagrave(k) (A)g = f

int result = 0

for (int k = 0 k lt= n k++)

int tmp = (k)Ckn times f

if (k 2 == 0) result += tmp else result -= tmp

Lời kết Trecircn đacircy lagrave phần trigravenh bagravey lời giải của migravenh Lời giải nagravey giagravenh phần lớn dung

lượng để giải thiacutech caacutech sử dụng nguyecircn lyacute bao hagravem loại trừ Với những bạn đatilde lagravem quen với nguyecircn lyacute nagravey từ lacircu caacutec bạn chỉ cần đọc lời giải đến phần Đếm số datildey nhị phacircn R bit 1 lagrave đủ Tuy nhiecircn coacute nhiều bạn ở Việt Nam dugrave học chuyecircn tin nhưng lại iacutet học toaacuten vagrave mới nghe qua khaacutei niệm nagravey lần đầu sẽ cảm thấy xa lạ với caacutech giải nagravey Cũng xin noacutei thecircm rằng caacutech suy luận migravenh đatilde trigravenh bagravey ở trecircn mang đậm tiacutenh suy luận trực giaacutec vagrave coacute phần thiếu chặt chẽ với mục điacutech giuacutep caacutec bạn iacutet tiếp xuacutec với toaacuten dễ cảm thụ hơn Dugrave migravenh đatilde chứng minh chặt chẽ được bằng toaacuten học mọi kết quả của bagravei toaacuten nagravey migravenh xin pheacutep khocircng trigravenh bagravey tại đacircy Hơn nữa ngagravey đầu tiecircn học nguyecircn lyacute bao hagravem vagrave loại trừ migravenh đatilde sử dụng caacutech suy luận ở trecircn để khiến những dograveng suy luận thecircm phần gần gũi

Lời giải 2 Nguyễn Đinh Quang Minh (team VNU - unsigned) Trước hết vigrave hai chồng rượu liecircn tiếp phải khaacutec magraveu nhau necircn ta coacute thể ldquotrảirdquo caacutec hộp rượu thagravenh hagraveng ngang Noacutei caacutech khaacutec mỗi cấu higravenh thỏa matilden tương đương với một caacutech xếp tất cả R + W hộp rượu thagravenh hagraveng ngang sao cho khocircng coacute d hộp rượu vang đỏ liecircn tiếp

Vigrave khocircng coacute ragraveng buộc nagraveo liecircn quan tới rượu trắng ta sẽ xacircy dựng một cấu higravenh thỏa matilden như sau

+ Đặt W hộp rượu trắng vagraveo trước tạo thagravenh W+1 ldquokhoảngrdquo để đặt rượu đỏ vagraveo + Đặt R hộp rượu đỏ vagraveo caacutec khoảng sao cho khocircng coacute khoảng nagraveo chứa nhiều hơn d

hộp Noacutei caacutech khaacutec nếu coi lagrave số hộp rượu đỏ nằm trong từng khoảng thigrave số cấu

higravenh thỏa matilden lagrave số bộ thỏa matilden vagrave

Xeacutet đa thức ta thấy hệ số chiacutenh lagrave số cấu higravenh thỏa matilden Biến đổi đa thức f

Theo khai triển Newton ta coacute

Aacutep dụng cocircng thức Taylor

Nhacircn vagraveo được

Thay ta được

Vậy

Ta coacute thể tiacutenh tổng trecircn trong độ phức tạp O(R+W)

B - Barcode (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Tổ hợp Tiacutenh nghịch đảo modulo Sagraveng số nguyecircn tố Ta xem một barcode tương đương một xacircu coacute độ dagravei N gồm caacutec kiacute tự lsquoBrsquo (magraveu xanh) hoặc lsquoRrsquo (magraveu đỏ) Gọi S 1 lagrave số chuỗi thỏa matilden yecircu cầu thứ nhất (số kiacute tự lsquoBrsquo bằng số kiacute tự lsquoRrsquo) S 2 lagrave số chuỗi thỏa matilden yecircu cầu thứ hai (khocircng coacute hai kiacute tự lsquoBrsquo liecircn tiếp) S 12 lagrave số chuỗi thỏa matilden cả hai yecircu cầu trecircn Đaacutep số bagravei toaacuten lagrave S 1 + S2 - S12

Tiacutenh S1 Nếu N lẻ hiển nhiecircn S 1 = 0 Ngược lại S 1 lagrave số caacutech chọn N2 vị triacute để gaacuten cho kiacute tự lsquoBrsquo trong số N vị triacute của xacircu Noacutei caacutech khaacutec S 1 = C(N N2) Tiacutenh S2 Gọi dp[i][0] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoBrsquo thỏa matilden yecircu cầu thứ hai dp[i][1] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoRrsquo thỏa matilden yecircu cầu thứ hai F[i] = dp[i][0]+dp[i][1] Ta coacute

dp[i][0] = dp[i-1][1] dp[i][1] = dp[i-1][0]+dp[i-1][1]

rArr F[i] = dp[i][0] + dp[i][1] = dp[i-1][1] + dp[i-1][0] + dp[i-1][1] = dp[i-2][0] + dp[i-2][1] + dp[i-1][0] + dp[i-1][1] = F[i-2] + F[i-1] Vậy F[i] chiacutenh lagrave số Fibonacci thứ i rArr S 2 chiacutenh lagrave số Fibonacci thứ N Tiacutenh S12 Nếu N lẻ hiển nhiecircn S 12 = 0 Ngược lại ta nhận xeacutet lagrave sẽ coacute khocircng quaacute 1 vị triacute coacute hai kiacute tự lsquoRrsquo liecircn tiếp nhau Ta coacute caacutec trường hợp sau

ldquoRBRBRBrdquo ldquoBRBRBRrdquo ldquoRBRBRRBRBRrdquo (coacute n2 - 1 xacircu)

Như vậy S 12 = n2 + 1 Vấn đề cograven lại lagrave tiacutenh C(N N2) modulo M Ta phacircn tiacutech C(N N2) thagravenh tiacutech caacutec thừa số nguyecircn tố C(N N2) = tiacutech(pi ^ ki) với pi lagrave số nguyecircn tố trong khoảng [1 N] Xeacutet lần lượt caacutec số nguyecircn tố trong khoảng [1 N] (coacute thể dugraveng sagraveng để liệt kecirc caacutec số nguyecircn tố) để tiacutenh ki ta lagravem như sau

Đặt f(N p) = x với x lagrave luỹ thừa lớn nhất của p magrave N chia hết cho p^x

Vigrave C(N N2) = N (N2) (N2) necircn ki = f(N p) - f(N2 p) - f(N2 p) Để tiacutenh f(N p) ta lần lượt đếm số lần xuất hiện của p trong khoảng [1 N] rồi đếm số lần

xuất hiện của p^2 trong khoảng [1 N] Ta coacute thể code đệ quy rất đơn giản như sau int f(int N int p) if (N lt p) return 0 return N p + f(Np p) Vigrave số lượng số nguyecircn tố trong khoảng [1 N] lagrave O(NlogN) vagrave độ phức tạp mỗi lần gọi f() lagrave O(logN) necircn ta coacute độ phức tạp với mỗi test lagrave O(N)

Lưu yacute Coacute rất nhiều team lagravem sai bagravei nagravey do tầng tầng lớp lớp caacutec bẫy magrave người ra đề đặt ra

Nếu ldquomắt nhanh hơn natildeordquo magrave nhigraven vagraveo test viacute dụ ta rất dễ lầm tưởng đaacutep aacuten lagrave số Fibonacci thứ n Điều nagravey chỉ đuacuteng với n lẻ (vagrave vocirc tigravenh đuacuteng với n = 2)

Trong quaacute trigravenh tiacutenh C(n n2) = thigrave cần chuacute yacute lagrave ta khocircng thể aacutep dụng cocircng thức a -1 equiv aM-2 (mod M) (hệ quả của Định liacute Euler ) được do với giới hạn M đề bagravei cho thigrave (n2) Vagrave M coacute thể khocircng nguyecircn tố cugraveng nhau Người ra đề cograven cố tigravenh cho dữ kiện M lagrave số nguyecircn tố nhằm gagravei bẫy caacutec thiacute sinh khocircng hiểu rotilde bản chất của định liacute Euler

Những bạn nagraveo bị sai lỗi nagravey hatildey đọc lại bagravei viết trecircn VNOI 10 lần Tiacutenh nghịch đảo modulo

C - Cu Chi Tunnel (1)

Taacutec giả Lecirc Đocircn Khuecirc

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Tham lam Ta sẽ tiến hagravenh gắn caacutec đỉnh vagraveo cacircy theo thứ tự từ 2 đến N Khi đoacute với đỉnh thứ i ta coacute thể gắn noacute vagraveo bất kigrave đỉnh nagraveo beacute hơn i magrave chưa đủ bậc Nếu tất cả caacutec đỉnh đều đatilde đủ bậc thigrave cacircu trả lời lagrave ldquoNOrdquo Cuối cugraveng nếu đatilde gắn xong đỉnh N magrave vẫn cograven đỉnh khocircng đủ bậc thigrave cũng in ra ldquoNOrdquo Viacute dụ 8

3 2 2 1 1 3 1 1

Đỉnh 2 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 1 1 0 0 0 0 0 0 Đỉnh 3 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 2 1 1 0 0 0 0 0 Đỉnh 4 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 3 1 1 1 0 0 0 0 Đỉnh 5 gắn với đỉnh 2 Mảng bậc hiện tại lagrave 3 2 1 1 1 0 0 0 Đỉnh 6 gắn với đỉnh 3 Mảng bậc hiện tại lagrave 3 2 2 1 1 1 0 0 Đỉnh 7 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 2 1 0 Đỉnh 8 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 3 1 1 Ta coacute thuật toaacuten độ phức tạp O(N^2) đủ để AC bagravei nagravey Nhưng ta coacute thể cải tiến thecircm bằng caacutech nhận xeacutet rằng ta chỉ cần quan tacircm đến tổng bậc cograven thiếu của caacutec đỉnh đatilde được gắn vagraveo cacircy magrave khocircng cần quan tacircm đến bậc cograven thiếu của từng đỉnh Do đoacute trong quaacute trigravenh duyệt ta chỉ cần lưu một biến cnt lagrave tổng bậc cograven thiếu hiện tại Độ phức tạp O(N)

D - Dropping Ball (4)

Taacutec giả Nguyễn Thagravenh Trung (RR)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned) Toacutem tắt đề bagravei Cho một bảng N x M với mỗi ocirc trong bảng coacute một trong 2 loại thanh lsquorsquo hoặc lsquorsquo Ta coacute Q truy vấn

- Đổi tường của một ocirc (ij) - Hỏi xem nếu thả một quả boacuteng vagraveo cột i thigrave quả boacuteng coacute thể xuống hagraveng cuối cugraveng rồi

ra khỏi bảng khocircng

Lời giải tracircu Để giải được toagraven bộ bagravei nagravey trước tiecircn ta phải nghĩ ra một lời giải tracircu nagraveo đoacute rồi tigravem caacutech cải tiến nếu coacute thể tuỳ vagraveo lời giải tracircu như nagraveo magrave cải tiến khaacutec nhau Coacute thể coi một ocirc (ij) bằng 2 nửa nửa trecircn vagrave nửa dưới Coi mỗi một nửa lagrave một đỉnh trecircn đồ thị Coacute thể dễ dagraveng nhận thấy mỗi một đỉnh nagravey chỉ coacute một đỉnh ra duy nhất tuỳ vagraveo loại thanh của caacutec ocirc xung quanh Nếu lagrave nửa dưới thigrave noacute chỉ coacute cạnh đi xuống dưới cograven nếu lagrave nửa trecircn thigrave noacute chỉ coacute cạnh đi sang một trong 2 ocirc becircn cạnh cugraveng hagraveng noacute Vậy với lời giải nagravey chỉ cần bfs lại toagraven bảng mỗi khi coacute truy vấn hỏi quả boacuteng đi đacircu

Lời giải tối ưu Lấy yacute tưởng bagravei httpcodeforcescomproblemsetproblem13E cugraveng với việc nhận ra N x M lt= 100 000 Migravenh đatilde coacute yacute tưởng chia bảng thagravenh những block caacutec hagraveng liecircn tiếp nhau mỗi block chứa xấp xỉ sqrt(N x M) ocirc Với mỗi block ta lưu lại được nếu thả quả boacuteng vagraveo cột j ở đầu block thigrave đến cuối block quả boacuteng sẽ ở cột nagraveo sử dụng lời giải tracircu ở trecircn Do vậy

- Truy vấn loại update ta thực hiện lại lời giải tracircu với tất cả caacutec ocirc thuộc block chứa ocirc (ij) cần update thực hiện lại việc bfs trecircn bảng Độ phức tạp thực hiện cocircng việc nagravey lagrave O(số ocirc của block) = O(sqrt(N x M)) Sau khi update với mỗi block ta coacute mảng nxt[j] = ocirc magrave quả boacuteng sẽ rơi xuống ở cuối block nếu quả boacuteng được thả ở cột j của block

- Truy vấn loại yecircu cầu trả lời Đi từ block 1 nhảy đến hagraveng đầu tiecircn của block 2 sử dụng thocircng tin trong block 1 tiếp tụchellip cho đến hết bảng Độ phức tạp (N x M (độ lớn mỗi block)) = O(sqrt(N x M))

Thế nhưng với trường hợp số hagraveng rất iacutet số cột rất to ta khocircng thể chia lagravem caacutec block sao cho mỗi block coacute iacutet hơn sqrt(N x M) phần tử được Do vậy với trường hợp N lt= sqrt(N x M) ta phải giải tracircu tức lagrave đi từ trecircn xuống dưới mỗi truy vấn mất đpt O(N) Thuật toaacuten nagravey bọn migravenh cảm thấy rất dễ code Với sự tinh tế của Nguyecircn team Unsigned đatilde hoagraven thagravenh việc code trong chỉ 15 phuacutet nộp phaacutet AC luocircn trong sự thăng hoa của team

E - Engaging with Loyal Customers (2) Thể loại Đồ thị Cặp gheacutep Lời giải Đacircy lagrave bagravei toaacuten cặp gheacutep coacute trọng số cực đại Để lagravem được bagravei nagravey caacutec bạn cần nắm vững Cặp gheacutep coacute trọng số trong saacutech thầy Lecirc Minh Hoagraveng (link) Cagravei đặt thuật toaacuten Hungary để giải Cặp gheacutep coacute trọng số code Một thuật toaacuten khaacutec cũng coacute thể dugraveng để giải cặp gheacutep coacute trọng số lagrave luồng mincost ( code) tuy nhiecircn khocircng thể chạy đủ nhanh vigrave đồ thị bagravei nagravey coacute 10^6 cạnh

F - Famous Pagoda (3)

Lời giải Nguyễn Thagravenh Trung - RR Thể loại Tối ưu hoaacute Quy hoạch động - Chia để trị Đặt cost(i j) lagrave chi phiacute để xacircy cầu thang từ điểm i đến j Đặt f(k i) = chi phiacute nhỏ nhất để k nhoacutem thợ xacircy tất cả cầu thang từ 1 đến i Ta coacute cocircng thức QHĐ

f(k i) = min( f(k-1 j) + cost(j+1 i) với j = 1i-1) Kết quả của bagravei toaacuten chiacutenh lagrave f(G N) Coacute 2 điểm mấu chốt của bagravei nagravey

Tiacutenh cost(i j) Tiacutenh nhanh bảng f(k i) Nếu tiacutenh trực tiếp theo cocircng thức trecircn ta mất độ phức tạp

O(GN^2) khocircng đủ để AC bagravei nagravey

1 Tiacutenh cost(i j) Với k = 1

Khi k = 1 điểm v chiacutenh lagrave median của datildey A(i)A(j) Do datildey A đatilde được sắp xếp tăng dần v = A[i + (j - i + 1) 2] Với mỗi (i j) ta coacute thể tiacutenh nhanh cost(i j) trong O(1) bằng mảng cộng dồn

Với k = 2

Đặt L = số phần tử của đoạn A(i)A(j) = j - i + 1 cost(i j) = sum( (a(s) - v)^2 )

= sum( a(s)^2 ) + Lv^2 + 2sum( a(s) )v Đặt B = 2sum( a(s) ) C = sum( a(s)^2 ) Ta tiacutenh được B vagrave C trong O(1) bằng mảng

cộng dồn cost(i j) = Lv^2 + Bv + C lagrave một hagravem bậc 2 của v Do đoacute điểm v để lagravem cost(i j) nhỏ

nhất chiacutenh lagrave v = -B L Tuy nhiecircn (-B L) coacute thể lagrave số thực cograven trong bagravei toaacuten nagravey v phải lagrave số nguyecircn necircn ta cần xeacutet 2 số nguyecircn v gần nhất với (-B L) bởi vigrave đồ thị hagravem số lồi

2 Tiacutenh f(k i) Để tiacutenh f(k i) ta cần dugraveng kĩ thuật QHĐ chia để trị Bạn coacute thể đọc lyacute thuyết ở VNOI wiki vagrave code ở đacircy Trong lời giải nagravey migravenh chỉ tập trung vagraveo việc chứng minh tiacutenh đuacuteng đắn của thuật toaacuten Nhắc lại ta coacute thể sử dụng được QHĐ chia để trị nếu

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 2: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

Lời giải được đoacuteng goacutep bởi Lecirc Quang Tuấn Nguyễn Đinh Quang Minh Phạm Cao Nguyecircn - team VNU - unsigned Nguyễn Diệp Xuacircn Quang - team HCMUS Illuminate Phạm Văn Hạnh Nguyễn Thagravenh Trung - RR Lecirc Đocircn Khuecirc Lăng Trung Hiếu

Nếu coacute thắc mắc về lời giải bạn coacute thể hỏi ở group VNOI Trong caacutec lời giải coacute sử dụng 1 số bagravei viết trecircn VNOI wiki

Sagraveng số nguyecircn tố Tiacutenh nghịch đảo modulo Tối ưu hoaacute QHĐ Kĩ thuật bao lồi Caacutec chủ đề về đồ thị

Caacutec bạn coacute thể nộp thử bagravei ở Kattis Code mẫu httpsgithubcomacmicpc-vietnamacmicpc-vietnamgithubiotreemaster2017regional Bảng xếp hạng cuối cugraveng httpshochiminh17kattiscomstandings

A Arranging Wine (5)

Taacutec giả Lăng Trung Hiếu

Lời giải 1 Phạm Văn Hạnh Thể loại Tổ hợp Inclusion-Exclusion Nhận xeacutet Giả sử ta xếp caacutec thugraveng rượu thagravenh một hagraveng ngang gồm R + W thugraveng rượu sau đoacute xếp caacutec thugraveng rượu liecircn tiếp cugraveng magraveu vagraveo một chồng ta sẽ được một datildey caacutec chồng rượu vang đỏ trắng xen kẽ (mỗi chồng chứa đuacuteng một loại rượu vagrave hai chồng cạnh nhau coacute rượu khaacutec magraveu) Do đoacute bagravei toaacuten coacute thể phaacutet biểu lại như sau

Đếm số datildey nhị phacircn gồm R bit 1 vagrave W bit 0 sao cho coacute khocircng quaacute D bit 1 liecircn tiếp Ta xếp W bit 0 lecircn datildey vagrave lần lượt đặt R bit 1 vagraveo đagraveu datildey cuối datildey hoặc xen giữa caacutec bit 0 Bagravei toaacuten đoacute được chuyển về bagravei toaacuten tổng quaacutet sau đacircy

Đếm số datildey số nguyecircn khocircng acircm coacute vagrave x )( 1 x2 xn sumn

i=1xi = S forall10 le xi le k le i le n

Để giải quyết bagravei toaacuten nagravey ta sử dụng nguyecircn lyacute bao hagravem loại trừ với mục điacutech đưa về bagravei toaacuten dễ giải hơn - bagravei toaacuten khocircng coacute ragraveng buộc Đaacutep số bagravei toaacuten khi đoacute lagrave Phầnxi le k Cnminus1

S+nminus1 chứng minh xin nhường lại cho bạn đọc Bagravei toaacuten sau đacircy cũng coacute lời giải đơn giản lagrave hệ quả của bagravei toaacuten đơn giản phiacutea trecircn Cho

đếm số datildey coacute vagrave 1 Asub 2 n x )( 1 x2 xn sumn

i=1xi = S foralliisin0 le xi A forallik lt xi isin A

Vai trograve của tập hợp A trong datildey trecircn lagrave với mọi ta biết chắc chắn lagrave phần tử xấuiisin A xi Ngược lại nếu coacute thể xấu cũng coacute thể tốt (coacute thể hoặc ta chưax )( i gt k isini A xi xi le k xi gt k

rotilde) Gọi lagrave đaacutep số của bagravei toaacuten trecircn với tập hợp A lagrave tập hợp caacutec phần tử chắc chắn xấu Để(A)f tigravem đaacutep số của bagravei toaacuten ban đầu (tigravem số datildey khocircng chứa phần từ xấu) ta nghĩ tớix )( 1 x2 xn yacute tưởng sau Gọi lagrave đaacutep số của bagravei toaacutenesultr

0 Đầu tiecircn ta giả sử đaacutep số bagravei toaacuten lagrave số datildey magrave caacutec phần tử coacute thể tốt hoặc xấu tugravey yacute Sau đoacute ta tigravem caacutech loại đi những đaacutep aacuten xấu

int result = f(empty) 1 Đầu tiecircn ta sẽ loại bỏ caacutec datildey coacute chiacutenh xaacutec một phần tử xấu nghĩa lagrave

for (int i = 1 i lt= n i++)

result -= f(i)

2 Sau bước vừa rồi ta thấy trong result khocircng chứa caacutec datildey coacute duy nhất một phần tử xấu Tuy nhiecircn những datildey coacute chiacutenh xaacutec hai phần tử xấu vừa bị trừ 2 lần ở bước trecircn nghĩa lagrave đang bị trừ thừa 1 lần necircn giờ phải cộng ngược lại

for (int i = 1 i lt= n i++)

for (int j = i + 1 j lt= n j++)

result += f(i j)

3 Sau bước vừa rồi ta đatilde hoagraven toagraven loại bỏ khỏi result những datildey coacute chiacutenh xaacutec một hoặc hai phần tử xấu Giờ ta muốn loại bỏ khỏi result những datildey coacute chiacutenh xaacutec ba phần tử xấu Hatildey quan saacutet những datildey nagravey đatilde bị tiacutenh bao nhiecircu lần ở result trong ba bước trecircn Ở bước 0 mỗi datildey được cộng 1 lần Ở bước 1 mỗi datildey bị trừ 3 lần (Một datildey coacute ba vị triacute xấu

sẽ được tiacutenh trong ) Tới bước 2 mỗi datildey lại được cộng lại ba lần x y z (x) (y) (z)f f f (Một datildey coacute ba vị triacute xấu sẽ được tiacutenh trong ) Như vậy hiện tại x y z (x ) (y ) (z )f y f z f x mỗi datildey coacute chiacutenh xaacutec ba phần tử xấu hiện đang được tiacutenh 1 lần trong result Cocircng việc của ta bacircy giờ lagrave trừ noacute đi

for (int i = 1 i lt= n i++)

for (int j = i + 1 j lt= n j++)

for (int k = j + 1 k lt= n k++)

result -= f(i j k)

hellip Tiếp tục lập luận tương tự ta đi tới quy tắc tiacutenh sau đacircy Xeacutet mọi tập con A của

Nếu A coacute chẵn phần tử ta cộng thecircm vagraveo result Ngược lại nếu A coacute lẻ phần1 2 n (A)f tử ta trừ đi ở result (A)f

Dễ thấy giaacute trị của chỉ phụ thuộc vagraveo lực lượng của tập hợp A ta kyacute hiệu(A)f với tập hợp A tugravey yacute coacute K phần tử Thuật toaacuten chuẩn của bagravei toaacuten lagrave(k) (A)g = f

int result = 0

for (int k = 0 k lt= n k++)

int tmp = (k)Ckn times f

if (k 2 == 0) result += tmp else result -= tmp

Lời kết Trecircn đacircy lagrave phần trigravenh bagravey lời giải của migravenh Lời giải nagravey giagravenh phần lớn dung

lượng để giải thiacutech caacutech sử dụng nguyecircn lyacute bao hagravem loại trừ Với những bạn đatilde lagravem quen với nguyecircn lyacute nagravey từ lacircu caacutec bạn chỉ cần đọc lời giải đến phần Đếm số datildey nhị phacircn R bit 1 lagrave đủ Tuy nhiecircn coacute nhiều bạn ở Việt Nam dugrave học chuyecircn tin nhưng lại iacutet học toaacuten vagrave mới nghe qua khaacutei niệm nagravey lần đầu sẽ cảm thấy xa lạ với caacutech giải nagravey Cũng xin noacutei thecircm rằng caacutech suy luận migravenh đatilde trigravenh bagravey ở trecircn mang đậm tiacutenh suy luận trực giaacutec vagrave coacute phần thiếu chặt chẽ với mục điacutech giuacutep caacutec bạn iacutet tiếp xuacutec với toaacuten dễ cảm thụ hơn Dugrave migravenh đatilde chứng minh chặt chẽ được bằng toaacuten học mọi kết quả của bagravei toaacuten nagravey migravenh xin pheacutep khocircng trigravenh bagravey tại đacircy Hơn nữa ngagravey đầu tiecircn học nguyecircn lyacute bao hagravem vagrave loại trừ migravenh đatilde sử dụng caacutech suy luận ở trecircn để khiến những dograveng suy luận thecircm phần gần gũi

Lời giải 2 Nguyễn Đinh Quang Minh (team VNU - unsigned) Trước hết vigrave hai chồng rượu liecircn tiếp phải khaacutec magraveu nhau necircn ta coacute thể ldquotrảirdquo caacutec hộp rượu thagravenh hagraveng ngang Noacutei caacutech khaacutec mỗi cấu higravenh thỏa matilden tương đương với một caacutech xếp tất cả R + W hộp rượu thagravenh hagraveng ngang sao cho khocircng coacute d hộp rượu vang đỏ liecircn tiếp

Vigrave khocircng coacute ragraveng buộc nagraveo liecircn quan tới rượu trắng ta sẽ xacircy dựng một cấu higravenh thỏa matilden như sau

+ Đặt W hộp rượu trắng vagraveo trước tạo thagravenh W+1 ldquokhoảngrdquo để đặt rượu đỏ vagraveo + Đặt R hộp rượu đỏ vagraveo caacutec khoảng sao cho khocircng coacute khoảng nagraveo chứa nhiều hơn d

hộp Noacutei caacutech khaacutec nếu coi lagrave số hộp rượu đỏ nằm trong từng khoảng thigrave số cấu

higravenh thỏa matilden lagrave số bộ thỏa matilden vagrave

Xeacutet đa thức ta thấy hệ số chiacutenh lagrave số cấu higravenh thỏa matilden Biến đổi đa thức f

Theo khai triển Newton ta coacute

Aacutep dụng cocircng thức Taylor

Nhacircn vagraveo được

Thay ta được

Vậy

Ta coacute thể tiacutenh tổng trecircn trong độ phức tạp O(R+W)

B - Barcode (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Tổ hợp Tiacutenh nghịch đảo modulo Sagraveng số nguyecircn tố Ta xem một barcode tương đương một xacircu coacute độ dagravei N gồm caacutec kiacute tự lsquoBrsquo (magraveu xanh) hoặc lsquoRrsquo (magraveu đỏ) Gọi S 1 lagrave số chuỗi thỏa matilden yecircu cầu thứ nhất (số kiacute tự lsquoBrsquo bằng số kiacute tự lsquoRrsquo) S 2 lagrave số chuỗi thỏa matilden yecircu cầu thứ hai (khocircng coacute hai kiacute tự lsquoBrsquo liecircn tiếp) S 12 lagrave số chuỗi thỏa matilden cả hai yecircu cầu trecircn Đaacutep số bagravei toaacuten lagrave S 1 + S2 - S12

Tiacutenh S1 Nếu N lẻ hiển nhiecircn S 1 = 0 Ngược lại S 1 lagrave số caacutech chọn N2 vị triacute để gaacuten cho kiacute tự lsquoBrsquo trong số N vị triacute của xacircu Noacutei caacutech khaacutec S 1 = C(N N2) Tiacutenh S2 Gọi dp[i][0] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoBrsquo thỏa matilden yecircu cầu thứ hai dp[i][1] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoRrsquo thỏa matilden yecircu cầu thứ hai F[i] = dp[i][0]+dp[i][1] Ta coacute

dp[i][0] = dp[i-1][1] dp[i][1] = dp[i-1][0]+dp[i-1][1]

rArr F[i] = dp[i][0] + dp[i][1] = dp[i-1][1] + dp[i-1][0] + dp[i-1][1] = dp[i-2][0] + dp[i-2][1] + dp[i-1][0] + dp[i-1][1] = F[i-2] + F[i-1] Vậy F[i] chiacutenh lagrave số Fibonacci thứ i rArr S 2 chiacutenh lagrave số Fibonacci thứ N Tiacutenh S12 Nếu N lẻ hiển nhiecircn S 12 = 0 Ngược lại ta nhận xeacutet lagrave sẽ coacute khocircng quaacute 1 vị triacute coacute hai kiacute tự lsquoRrsquo liecircn tiếp nhau Ta coacute caacutec trường hợp sau

ldquoRBRBRBrdquo ldquoBRBRBRrdquo ldquoRBRBRRBRBRrdquo (coacute n2 - 1 xacircu)

Như vậy S 12 = n2 + 1 Vấn đề cograven lại lagrave tiacutenh C(N N2) modulo M Ta phacircn tiacutech C(N N2) thagravenh tiacutech caacutec thừa số nguyecircn tố C(N N2) = tiacutech(pi ^ ki) với pi lagrave số nguyecircn tố trong khoảng [1 N] Xeacutet lần lượt caacutec số nguyecircn tố trong khoảng [1 N] (coacute thể dugraveng sagraveng để liệt kecirc caacutec số nguyecircn tố) để tiacutenh ki ta lagravem như sau

Đặt f(N p) = x với x lagrave luỹ thừa lớn nhất của p magrave N chia hết cho p^x

Vigrave C(N N2) = N (N2) (N2) necircn ki = f(N p) - f(N2 p) - f(N2 p) Để tiacutenh f(N p) ta lần lượt đếm số lần xuất hiện của p trong khoảng [1 N] rồi đếm số lần

xuất hiện của p^2 trong khoảng [1 N] Ta coacute thể code đệ quy rất đơn giản như sau int f(int N int p) if (N lt p) return 0 return N p + f(Np p) Vigrave số lượng số nguyecircn tố trong khoảng [1 N] lagrave O(NlogN) vagrave độ phức tạp mỗi lần gọi f() lagrave O(logN) necircn ta coacute độ phức tạp với mỗi test lagrave O(N)

Lưu yacute Coacute rất nhiều team lagravem sai bagravei nagravey do tầng tầng lớp lớp caacutec bẫy magrave người ra đề đặt ra

Nếu ldquomắt nhanh hơn natildeordquo magrave nhigraven vagraveo test viacute dụ ta rất dễ lầm tưởng đaacutep aacuten lagrave số Fibonacci thứ n Điều nagravey chỉ đuacuteng với n lẻ (vagrave vocirc tigravenh đuacuteng với n = 2)

Trong quaacute trigravenh tiacutenh C(n n2) = thigrave cần chuacute yacute lagrave ta khocircng thể aacutep dụng cocircng thức a -1 equiv aM-2 (mod M) (hệ quả của Định liacute Euler ) được do với giới hạn M đề bagravei cho thigrave (n2) Vagrave M coacute thể khocircng nguyecircn tố cugraveng nhau Người ra đề cograven cố tigravenh cho dữ kiện M lagrave số nguyecircn tố nhằm gagravei bẫy caacutec thiacute sinh khocircng hiểu rotilde bản chất của định liacute Euler

Những bạn nagraveo bị sai lỗi nagravey hatildey đọc lại bagravei viết trecircn VNOI 10 lần Tiacutenh nghịch đảo modulo

C - Cu Chi Tunnel (1)

Taacutec giả Lecirc Đocircn Khuecirc

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Tham lam Ta sẽ tiến hagravenh gắn caacutec đỉnh vagraveo cacircy theo thứ tự từ 2 đến N Khi đoacute với đỉnh thứ i ta coacute thể gắn noacute vagraveo bất kigrave đỉnh nagraveo beacute hơn i magrave chưa đủ bậc Nếu tất cả caacutec đỉnh đều đatilde đủ bậc thigrave cacircu trả lời lagrave ldquoNOrdquo Cuối cugraveng nếu đatilde gắn xong đỉnh N magrave vẫn cograven đỉnh khocircng đủ bậc thigrave cũng in ra ldquoNOrdquo Viacute dụ 8

3 2 2 1 1 3 1 1

Đỉnh 2 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 1 1 0 0 0 0 0 0 Đỉnh 3 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 2 1 1 0 0 0 0 0 Đỉnh 4 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 3 1 1 1 0 0 0 0 Đỉnh 5 gắn với đỉnh 2 Mảng bậc hiện tại lagrave 3 2 1 1 1 0 0 0 Đỉnh 6 gắn với đỉnh 3 Mảng bậc hiện tại lagrave 3 2 2 1 1 1 0 0 Đỉnh 7 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 2 1 0 Đỉnh 8 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 3 1 1 Ta coacute thuật toaacuten độ phức tạp O(N^2) đủ để AC bagravei nagravey Nhưng ta coacute thể cải tiến thecircm bằng caacutech nhận xeacutet rằng ta chỉ cần quan tacircm đến tổng bậc cograven thiếu của caacutec đỉnh đatilde được gắn vagraveo cacircy magrave khocircng cần quan tacircm đến bậc cograven thiếu của từng đỉnh Do đoacute trong quaacute trigravenh duyệt ta chỉ cần lưu một biến cnt lagrave tổng bậc cograven thiếu hiện tại Độ phức tạp O(N)

D - Dropping Ball (4)

Taacutec giả Nguyễn Thagravenh Trung (RR)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned) Toacutem tắt đề bagravei Cho một bảng N x M với mỗi ocirc trong bảng coacute một trong 2 loại thanh lsquorsquo hoặc lsquorsquo Ta coacute Q truy vấn

- Đổi tường của một ocirc (ij) - Hỏi xem nếu thả một quả boacuteng vagraveo cột i thigrave quả boacuteng coacute thể xuống hagraveng cuối cugraveng rồi

ra khỏi bảng khocircng

Lời giải tracircu Để giải được toagraven bộ bagravei nagravey trước tiecircn ta phải nghĩ ra một lời giải tracircu nagraveo đoacute rồi tigravem caacutech cải tiến nếu coacute thể tuỳ vagraveo lời giải tracircu như nagraveo magrave cải tiến khaacutec nhau Coacute thể coi một ocirc (ij) bằng 2 nửa nửa trecircn vagrave nửa dưới Coi mỗi một nửa lagrave một đỉnh trecircn đồ thị Coacute thể dễ dagraveng nhận thấy mỗi một đỉnh nagravey chỉ coacute một đỉnh ra duy nhất tuỳ vagraveo loại thanh của caacutec ocirc xung quanh Nếu lagrave nửa dưới thigrave noacute chỉ coacute cạnh đi xuống dưới cograven nếu lagrave nửa trecircn thigrave noacute chỉ coacute cạnh đi sang một trong 2 ocirc becircn cạnh cugraveng hagraveng noacute Vậy với lời giải nagravey chỉ cần bfs lại toagraven bảng mỗi khi coacute truy vấn hỏi quả boacuteng đi đacircu

Lời giải tối ưu Lấy yacute tưởng bagravei httpcodeforcescomproblemsetproblem13E cugraveng với việc nhận ra N x M lt= 100 000 Migravenh đatilde coacute yacute tưởng chia bảng thagravenh những block caacutec hagraveng liecircn tiếp nhau mỗi block chứa xấp xỉ sqrt(N x M) ocirc Với mỗi block ta lưu lại được nếu thả quả boacuteng vagraveo cột j ở đầu block thigrave đến cuối block quả boacuteng sẽ ở cột nagraveo sử dụng lời giải tracircu ở trecircn Do vậy

- Truy vấn loại update ta thực hiện lại lời giải tracircu với tất cả caacutec ocirc thuộc block chứa ocirc (ij) cần update thực hiện lại việc bfs trecircn bảng Độ phức tạp thực hiện cocircng việc nagravey lagrave O(số ocirc của block) = O(sqrt(N x M)) Sau khi update với mỗi block ta coacute mảng nxt[j] = ocirc magrave quả boacuteng sẽ rơi xuống ở cuối block nếu quả boacuteng được thả ở cột j của block

- Truy vấn loại yecircu cầu trả lời Đi từ block 1 nhảy đến hagraveng đầu tiecircn của block 2 sử dụng thocircng tin trong block 1 tiếp tụchellip cho đến hết bảng Độ phức tạp (N x M (độ lớn mỗi block)) = O(sqrt(N x M))

Thế nhưng với trường hợp số hagraveng rất iacutet số cột rất to ta khocircng thể chia lagravem caacutec block sao cho mỗi block coacute iacutet hơn sqrt(N x M) phần tử được Do vậy với trường hợp N lt= sqrt(N x M) ta phải giải tracircu tức lagrave đi từ trecircn xuống dưới mỗi truy vấn mất đpt O(N) Thuật toaacuten nagravey bọn migravenh cảm thấy rất dễ code Với sự tinh tế của Nguyecircn team Unsigned đatilde hoagraven thagravenh việc code trong chỉ 15 phuacutet nộp phaacutet AC luocircn trong sự thăng hoa của team

E - Engaging with Loyal Customers (2) Thể loại Đồ thị Cặp gheacutep Lời giải Đacircy lagrave bagravei toaacuten cặp gheacutep coacute trọng số cực đại Để lagravem được bagravei nagravey caacutec bạn cần nắm vững Cặp gheacutep coacute trọng số trong saacutech thầy Lecirc Minh Hoagraveng (link) Cagravei đặt thuật toaacuten Hungary để giải Cặp gheacutep coacute trọng số code Một thuật toaacuten khaacutec cũng coacute thể dugraveng để giải cặp gheacutep coacute trọng số lagrave luồng mincost ( code) tuy nhiecircn khocircng thể chạy đủ nhanh vigrave đồ thị bagravei nagravey coacute 10^6 cạnh

F - Famous Pagoda (3)

Lời giải Nguyễn Thagravenh Trung - RR Thể loại Tối ưu hoaacute Quy hoạch động - Chia để trị Đặt cost(i j) lagrave chi phiacute để xacircy cầu thang từ điểm i đến j Đặt f(k i) = chi phiacute nhỏ nhất để k nhoacutem thợ xacircy tất cả cầu thang từ 1 đến i Ta coacute cocircng thức QHĐ

f(k i) = min( f(k-1 j) + cost(j+1 i) với j = 1i-1) Kết quả của bagravei toaacuten chiacutenh lagrave f(G N) Coacute 2 điểm mấu chốt của bagravei nagravey

Tiacutenh cost(i j) Tiacutenh nhanh bảng f(k i) Nếu tiacutenh trực tiếp theo cocircng thức trecircn ta mất độ phức tạp

O(GN^2) khocircng đủ để AC bagravei nagravey

1 Tiacutenh cost(i j) Với k = 1

Khi k = 1 điểm v chiacutenh lagrave median của datildey A(i)A(j) Do datildey A đatilde được sắp xếp tăng dần v = A[i + (j - i + 1) 2] Với mỗi (i j) ta coacute thể tiacutenh nhanh cost(i j) trong O(1) bằng mảng cộng dồn

Với k = 2

Đặt L = số phần tử của đoạn A(i)A(j) = j - i + 1 cost(i j) = sum( (a(s) - v)^2 )

= sum( a(s)^2 ) + Lv^2 + 2sum( a(s) )v Đặt B = 2sum( a(s) ) C = sum( a(s)^2 ) Ta tiacutenh được B vagrave C trong O(1) bằng mảng

cộng dồn cost(i j) = Lv^2 + Bv + C lagrave một hagravem bậc 2 của v Do đoacute điểm v để lagravem cost(i j) nhỏ

nhất chiacutenh lagrave v = -B L Tuy nhiecircn (-B L) coacute thể lagrave số thực cograven trong bagravei toaacuten nagravey v phải lagrave số nguyecircn necircn ta cần xeacutet 2 số nguyecircn v gần nhất với (-B L) bởi vigrave đồ thị hagravem số lồi

2 Tiacutenh f(k i) Để tiacutenh f(k i) ta cần dugraveng kĩ thuật QHĐ chia để trị Bạn coacute thể đọc lyacute thuyết ở VNOI wiki vagrave code ở đacircy Trong lời giải nagravey migravenh chỉ tập trung vagraveo việc chứng minh tiacutenh đuacuteng đắn của thuật toaacuten Nhắc lại ta coacute thể sử dụng được QHĐ chia để trị nếu

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 3: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

A Arranging Wine (5)

Taacutec giả Lăng Trung Hiếu

Lời giải 1 Phạm Văn Hạnh Thể loại Tổ hợp Inclusion-Exclusion Nhận xeacutet Giả sử ta xếp caacutec thugraveng rượu thagravenh một hagraveng ngang gồm R + W thugraveng rượu sau đoacute xếp caacutec thugraveng rượu liecircn tiếp cugraveng magraveu vagraveo một chồng ta sẽ được một datildey caacutec chồng rượu vang đỏ trắng xen kẽ (mỗi chồng chứa đuacuteng một loại rượu vagrave hai chồng cạnh nhau coacute rượu khaacutec magraveu) Do đoacute bagravei toaacuten coacute thể phaacutet biểu lại như sau

Đếm số datildey nhị phacircn gồm R bit 1 vagrave W bit 0 sao cho coacute khocircng quaacute D bit 1 liecircn tiếp Ta xếp W bit 0 lecircn datildey vagrave lần lượt đặt R bit 1 vagraveo đagraveu datildey cuối datildey hoặc xen giữa caacutec bit 0 Bagravei toaacuten đoacute được chuyển về bagravei toaacuten tổng quaacutet sau đacircy

Đếm số datildey số nguyecircn khocircng acircm coacute vagrave x )( 1 x2 xn sumn

i=1xi = S forall10 le xi le k le i le n

Để giải quyết bagravei toaacuten nagravey ta sử dụng nguyecircn lyacute bao hagravem loại trừ với mục điacutech đưa về bagravei toaacuten dễ giải hơn - bagravei toaacuten khocircng coacute ragraveng buộc Đaacutep số bagravei toaacuten khi đoacute lagrave Phầnxi le k Cnminus1

S+nminus1 chứng minh xin nhường lại cho bạn đọc Bagravei toaacuten sau đacircy cũng coacute lời giải đơn giản lagrave hệ quả của bagravei toaacuten đơn giản phiacutea trecircn Cho

đếm số datildey coacute vagrave 1 Asub 2 n x )( 1 x2 xn sumn

i=1xi = S foralliisin0 le xi A forallik lt xi isin A

Vai trograve của tập hợp A trong datildey trecircn lagrave với mọi ta biết chắc chắn lagrave phần tử xấuiisin A xi Ngược lại nếu coacute thể xấu cũng coacute thể tốt (coacute thể hoặc ta chưax )( i gt k isini A xi xi le k xi gt k

rotilde) Gọi lagrave đaacutep số của bagravei toaacuten trecircn với tập hợp A lagrave tập hợp caacutec phần tử chắc chắn xấu Để(A)f tigravem đaacutep số của bagravei toaacuten ban đầu (tigravem số datildey khocircng chứa phần từ xấu) ta nghĩ tớix )( 1 x2 xn yacute tưởng sau Gọi lagrave đaacutep số của bagravei toaacutenesultr

0 Đầu tiecircn ta giả sử đaacutep số bagravei toaacuten lagrave số datildey magrave caacutec phần tử coacute thể tốt hoặc xấu tugravey yacute Sau đoacute ta tigravem caacutech loại đi những đaacutep aacuten xấu

int result = f(empty) 1 Đầu tiecircn ta sẽ loại bỏ caacutec datildey coacute chiacutenh xaacutec một phần tử xấu nghĩa lagrave

for (int i = 1 i lt= n i++)

result -= f(i)

2 Sau bước vừa rồi ta thấy trong result khocircng chứa caacutec datildey coacute duy nhất một phần tử xấu Tuy nhiecircn những datildey coacute chiacutenh xaacutec hai phần tử xấu vừa bị trừ 2 lần ở bước trecircn nghĩa lagrave đang bị trừ thừa 1 lần necircn giờ phải cộng ngược lại

for (int i = 1 i lt= n i++)

for (int j = i + 1 j lt= n j++)

result += f(i j)

3 Sau bước vừa rồi ta đatilde hoagraven toagraven loại bỏ khỏi result những datildey coacute chiacutenh xaacutec một hoặc hai phần tử xấu Giờ ta muốn loại bỏ khỏi result những datildey coacute chiacutenh xaacutec ba phần tử xấu Hatildey quan saacutet những datildey nagravey đatilde bị tiacutenh bao nhiecircu lần ở result trong ba bước trecircn Ở bước 0 mỗi datildey được cộng 1 lần Ở bước 1 mỗi datildey bị trừ 3 lần (Một datildey coacute ba vị triacute xấu

sẽ được tiacutenh trong ) Tới bước 2 mỗi datildey lại được cộng lại ba lần x y z (x) (y) (z)f f f (Một datildey coacute ba vị triacute xấu sẽ được tiacutenh trong ) Như vậy hiện tại x y z (x ) (y ) (z )f y f z f x mỗi datildey coacute chiacutenh xaacutec ba phần tử xấu hiện đang được tiacutenh 1 lần trong result Cocircng việc của ta bacircy giờ lagrave trừ noacute đi

for (int i = 1 i lt= n i++)

for (int j = i + 1 j lt= n j++)

for (int k = j + 1 k lt= n k++)

result -= f(i j k)

hellip Tiếp tục lập luận tương tự ta đi tới quy tắc tiacutenh sau đacircy Xeacutet mọi tập con A của

Nếu A coacute chẵn phần tử ta cộng thecircm vagraveo result Ngược lại nếu A coacute lẻ phần1 2 n (A)f tử ta trừ đi ở result (A)f

Dễ thấy giaacute trị của chỉ phụ thuộc vagraveo lực lượng của tập hợp A ta kyacute hiệu(A)f với tập hợp A tugravey yacute coacute K phần tử Thuật toaacuten chuẩn của bagravei toaacuten lagrave(k) (A)g = f

int result = 0

for (int k = 0 k lt= n k++)

int tmp = (k)Ckn times f

if (k 2 == 0) result += tmp else result -= tmp

Lời kết Trecircn đacircy lagrave phần trigravenh bagravey lời giải của migravenh Lời giải nagravey giagravenh phần lớn dung

lượng để giải thiacutech caacutech sử dụng nguyecircn lyacute bao hagravem loại trừ Với những bạn đatilde lagravem quen với nguyecircn lyacute nagravey từ lacircu caacutec bạn chỉ cần đọc lời giải đến phần Đếm số datildey nhị phacircn R bit 1 lagrave đủ Tuy nhiecircn coacute nhiều bạn ở Việt Nam dugrave học chuyecircn tin nhưng lại iacutet học toaacuten vagrave mới nghe qua khaacutei niệm nagravey lần đầu sẽ cảm thấy xa lạ với caacutech giải nagravey Cũng xin noacutei thecircm rằng caacutech suy luận migravenh đatilde trigravenh bagravey ở trecircn mang đậm tiacutenh suy luận trực giaacutec vagrave coacute phần thiếu chặt chẽ với mục điacutech giuacutep caacutec bạn iacutet tiếp xuacutec với toaacuten dễ cảm thụ hơn Dugrave migravenh đatilde chứng minh chặt chẽ được bằng toaacuten học mọi kết quả của bagravei toaacuten nagravey migravenh xin pheacutep khocircng trigravenh bagravey tại đacircy Hơn nữa ngagravey đầu tiecircn học nguyecircn lyacute bao hagravem vagrave loại trừ migravenh đatilde sử dụng caacutech suy luận ở trecircn để khiến những dograveng suy luận thecircm phần gần gũi

Lời giải 2 Nguyễn Đinh Quang Minh (team VNU - unsigned) Trước hết vigrave hai chồng rượu liecircn tiếp phải khaacutec magraveu nhau necircn ta coacute thể ldquotrảirdquo caacutec hộp rượu thagravenh hagraveng ngang Noacutei caacutech khaacutec mỗi cấu higravenh thỏa matilden tương đương với một caacutech xếp tất cả R + W hộp rượu thagravenh hagraveng ngang sao cho khocircng coacute d hộp rượu vang đỏ liecircn tiếp

Vigrave khocircng coacute ragraveng buộc nagraveo liecircn quan tới rượu trắng ta sẽ xacircy dựng một cấu higravenh thỏa matilden như sau

+ Đặt W hộp rượu trắng vagraveo trước tạo thagravenh W+1 ldquokhoảngrdquo để đặt rượu đỏ vagraveo + Đặt R hộp rượu đỏ vagraveo caacutec khoảng sao cho khocircng coacute khoảng nagraveo chứa nhiều hơn d

hộp Noacutei caacutech khaacutec nếu coi lagrave số hộp rượu đỏ nằm trong từng khoảng thigrave số cấu

higravenh thỏa matilden lagrave số bộ thỏa matilden vagrave

Xeacutet đa thức ta thấy hệ số chiacutenh lagrave số cấu higravenh thỏa matilden Biến đổi đa thức f

Theo khai triển Newton ta coacute

Aacutep dụng cocircng thức Taylor

Nhacircn vagraveo được

Thay ta được

Vậy

Ta coacute thể tiacutenh tổng trecircn trong độ phức tạp O(R+W)

B - Barcode (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Tổ hợp Tiacutenh nghịch đảo modulo Sagraveng số nguyecircn tố Ta xem một barcode tương đương một xacircu coacute độ dagravei N gồm caacutec kiacute tự lsquoBrsquo (magraveu xanh) hoặc lsquoRrsquo (magraveu đỏ) Gọi S 1 lagrave số chuỗi thỏa matilden yecircu cầu thứ nhất (số kiacute tự lsquoBrsquo bằng số kiacute tự lsquoRrsquo) S 2 lagrave số chuỗi thỏa matilden yecircu cầu thứ hai (khocircng coacute hai kiacute tự lsquoBrsquo liecircn tiếp) S 12 lagrave số chuỗi thỏa matilden cả hai yecircu cầu trecircn Đaacutep số bagravei toaacuten lagrave S 1 + S2 - S12

Tiacutenh S1 Nếu N lẻ hiển nhiecircn S 1 = 0 Ngược lại S 1 lagrave số caacutech chọn N2 vị triacute để gaacuten cho kiacute tự lsquoBrsquo trong số N vị triacute của xacircu Noacutei caacutech khaacutec S 1 = C(N N2) Tiacutenh S2 Gọi dp[i][0] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoBrsquo thỏa matilden yecircu cầu thứ hai dp[i][1] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoRrsquo thỏa matilden yecircu cầu thứ hai F[i] = dp[i][0]+dp[i][1] Ta coacute

dp[i][0] = dp[i-1][1] dp[i][1] = dp[i-1][0]+dp[i-1][1]

rArr F[i] = dp[i][0] + dp[i][1] = dp[i-1][1] + dp[i-1][0] + dp[i-1][1] = dp[i-2][0] + dp[i-2][1] + dp[i-1][0] + dp[i-1][1] = F[i-2] + F[i-1] Vậy F[i] chiacutenh lagrave số Fibonacci thứ i rArr S 2 chiacutenh lagrave số Fibonacci thứ N Tiacutenh S12 Nếu N lẻ hiển nhiecircn S 12 = 0 Ngược lại ta nhận xeacutet lagrave sẽ coacute khocircng quaacute 1 vị triacute coacute hai kiacute tự lsquoRrsquo liecircn tiếp nhau Ta coacute caacutec trường hợp sau

ldquoRBRBRBrdquo ldquoBRBRBRrdquo ldquoRBRBRRBRBRrdquo (coacute n2 - 1 xacircu)

Như vậy S 12 = n2 + 1 Vấn đề cograven lại lagrave tiacutenh C(N N2) modulo M Ta phacircn tiacutech C(N N2) thagravenh tiacutech caacutec thừa số nguyecircn tố C(N N2) = tiacutech(pi ^ ki) với pi lagrave số nguyecircn tố trong khoảng [1 N] Xeacutet lần lượt caacutec số nguyecircn tố trong khoảng [1 N] (coacute thể dugraveng sagraveng để liệt kecirc caacutec số nguyecircn tố) để tiacutenh ki ta lagravem như sau

Đặt f(N p) = x với x lagrave luỹ thừa lớn nhất của p magrave N chia hết cho p^x

Vigrave C(N N2) = N (N2) (N2) necircn ki = f(N p) - f(N2 p) - f(N2 p) Để tiacutenh f(N p) ta lần lượt đếm số lần xuất hiện của p trong khoảng [1 N] rồi đếm số lần

xuất hiện của p^2 trong khoảng [1 N] Ta coacute thể code đệ quy rất đơn giản như sau int f(int N int p) if (N lt p) return 0 return N p + f(Np p) Vigrave số lượng số nguyecircn tố trong khoảng [1 N] lagrave O(NlogN) vagrave độ phức tạp mỗi lần gọi f() lagrave O(logN) necircn ta coacute độ phức tạp với mỗi test lagrave O(N)

Lưu yacute Coacute rất nhiều team lagravem sai bagravei nagravey do tầng tầng lớp lớp caacutec bẫy magrave người ra đề đặt ra

Nếu ldquomắt nhanh hơn natildeordquo magrave nhigraven vagraveo test viacute dụ ta rất dễ lầm tưởng đaacutep aacuten lagrave số Fibonacci thứ n Điều nagravey chỉ đuacuteng với n lẻ (vagrave vocirc tigravenh đuacuteng với n = 2)

Trong quaacute trigravenh tiacutenh C(n n2) = thigrave cần chuacute yacute lagrave ta khocircng thể aacutep dụng cocircng thức a -1 equiv aM-2 (mod M) (hệ quả của Định liacute Euler ) được do với giới hạn M đề bagravei cho thigrave (n2) Vagrave M coacute thể khocircng nguyecircn tố cugraveng nhau Người ra đề cograven cố tigravenh cho dữ kiện M lagrave số nguyecircn tố nhằm gagravei bẫy caacutec thiacute sinh khocircng hiểu rotilde bản chất của định liacute Euler

Những bạn nagraveo bị sai lỗi nagravey hatildey đọc lại bagravei viết trecircn VNOI 10 lần Tiacutenh nghịch đảo modulo

C - Cu Chi Tunnel (1)

Taacutec giả Lecirc Đocircn Khuecirc

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Tham lam Ta sẽ tiến hagravenh gắn caacutec đỉnh vagraveo cacircy theo thứ tự từ 2 đến N Khi đoacute với đỉnh thứ i ta coacute thể gắn noacute vagraveo bất kigrave đỉnh nagraveo beacute hơn i magrave chưa đủ bậc Nếu tất cả caacutec đỉnh đều đatilde đủ bậc thigrave cacircu trả lời lagrave ldquoNOrdquo Cuối cugraveng nếu đatilde gắn xong đỉnh N magrave vẫn cograven đỉnh khocircng đủ bậc thigrave cũng in ra ldquoNOrdquo Viacute dụ 8

3 2 2 1 1 3 1 1

Đỉnh 2 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 1 1 0 0 0 0 0 0 Đỉnh 3 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 2 1 1 0 0 0 0 0 Đỉnh 4 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 3 1 1 1 0 0 0 0 Đỉnh 5 gắn với đỉnh 2 Mảng bậc hiện tại lagrave 3 2 1 1 1 0 0 0 Đỉnh 6 gắn với đỉnh 3 Mảng bậc hiện tại lagrave 3 2 2 1 1 1 0 0 Đỉnh 7 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 2 1 0 Đỉnh 8 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 3 1 1 Ta coacute thuật toaacuten độ phức tạp O(N^2) đủ để AC bagravei nagravey Nhưng ta coacute thể cải tiến thecircm bằng caacutech nhận xeacutet rằng ta chỉ cần quan tacircm đến tổng bậc cograven thiếu của caacutec đỉnh đatilde được gắn vagraveo cacircy magrave khocircng cần quan tacircm đến bậc cograven thiếu của từng đỉnh Do đoacute trong quaacute trigravenh duyệt ta chỉ cần lưu một biến cnt lagrave tổng bậc cograven thiếu hiện tại Độ phức tạp O(N)

D - Dropping Ball (4)

Taacutec giả Nguyễn Thagravenh Trung (RR)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned) Toacutem tắt đề bagravei Cho một bảng N x M với mỗi ocirc trong bảng coacute một trong 2 loại thanh lsquorsquo hoặc lsquorsquo Ta coacute Q truy vấn

- Đổi tường của một ocirc (ij) - Hỏi xem nếu thả một quả boacuteng vagraveo cột i thigrave quả boacuteng coacute thể xuống hagraveng cuối cugraveng rồi

ra khỏi bảng khocircng

Lời giải tracircu Để giải được toagraven bộ bagravei nagravey trước tiecircn ta phải nghĩ ra một lời giải tracircu nagraveo đoacute rồi tigravem caacutech cải tiến nếu coacute thể tuỳ vagraveo lời giải tracircu như nagraveo magrave cải tiến khaacutec nhau Coacute thể coi một ocirc (ij) bằng 2 nửa nửa trecircn vagrave nửa dưới Coi mỗi một nửa lagrave một đỉnh trecircn đồ thị Coacute thể dễ dagraveng nhận thấy mỗi một đỉnh nagravey chỉ coacute một đỉnh ra duy nhất tuỳ vagraveo loại thanh của caacutec ocirc xung quanh Nếu lagrave nửa dưới thigrave noacute chỉ coacute cạnh đi xuống dưới cograven nếu lagrave nửa trecircn thigrave noacute chỉ coacute cạnh đi sang một trong 2 ocirc becircn cạnh cugraveng hagraveng noacute Vậy với lời giải nagravey chỉ cần bfs lại toagraven bảng mỗi khi coacute truy vấn hỏi quả boacuteng đi đacircu

Lời giải tối ưu Lấy yacute tưởng bagravei httpcodeforcescomproblemsetproblem13E cugraveng với việc nhận ra N x M lt= 100 000 Migravenh đatilde coacute yacute tưởng chia bảng thagravenh những block caacutec hagraveng liecircn tiếp nhau mỗi block chứa xấp xỉ sqrt(N x M) ocirc Với mỗi block ta lưu lại được nếu thả quả boacuteng vagraveo cột j ở đầu block thigrave đến cuối block quả boacuteng sẽ ở cột nagraveo sử dụng lời giải tracircu ở trecircn Do vậy

- Truy vấn loại update ta thực hiện lại lời giải tracircu với tất cả caacutec ocirc thuộc block chứa ocirc (ij) cần update thực hiện lại việc bfs trecircn bảng Độ phức tạp thực hiện cocircng việc nagravey lagrave O(số ocirc của block) = O(sqrt(N x M)) Sau khi update với mỗi block ta coacute mảng nxt[j] = ocirc magrave quả boacuteng sẽ rơi xuống ở cuối block nếu quả boacuteng được thả ở cột j của block

- Truy vấn loại yecircu cầu trả lời Đi từ block 1 nhảy đến hagraveng đầu tiecircn của block 2 sử dụng thocircng tin trong block 1 tiếp tụchellip cho đến hết bảng Độ phức tạp (N x M (độ lớn mỗi block)) = O(sqrt(N x M))

Thế nhưng với trường hợp số hagraveng rất iacutet số cột rất to ta khocircng thể chia lagravem caacutec block sao cho mỗi block coacute iacutet hơn sqrt(N x M) phần tử được Do vậy với trường hợp N lt= sqrt(N x M) ta phải giải tracircu tức lagrave đi từ trecircn xuống dưới mỗi truy vấn mất đpt O(N) Thuật toaacuten nagravey bọn migravenh cảm thấy rất dễ code Với sự tinh tế của Nguyecircn team Unsigned đatilde hoagraven thagravenh việc code trong chỉ 15 phuacutet nộp phaacutet AC luocircn trong sự thăng hoa của team

E - Engaging with Loyal Customers (2) Thể loại Đồ thị Cặp gheacutep Lời giải Đacircy lagrave bagravei toaacuten cặp gheacutep coacute trọng số cực đại Để lagravem được bagravei nagravey caacutec bạn cần nắm vững Cặp gheacutep coacute trọng số trong saacutech thầy Lecirc Minh Hoagraveng (link) Cagravei đặt thuật toaacuten Hungary để giải Cặp gheacutep coacute trọng số code Một thuật toaacuten khaacutec cũng coacute thể dugraveng để giải cặp gheacutep coacute trọng số lagrave luồng mincost ( code) tuy nhiecircn khocircng thể chạy đủ nhanh vigrave đồ thị bagravei nagravey coacute 10^6 cạnh

F - Famous Pagoda (3)

Lời giải Nguyễn Thagravenh Trung - RR Thể loại Tối ưu hoaacute Quy hoạch động - Chia để trị Đặt cost(i j) lagrave chi phiacute để xacircy cầu thang từ điểm i đến j Đặt f(k i) = chi phiacute nhỏ nhất để k nhoacutem thợ xacircy tất cả cầu thang từ 1 đến i Ta coacute cocircng thức QHĐ

f(k i) = min( f(k-1 j) + cost(j+1 i) với j = 1i-1) Kết quả của bagravei toaacuten chiacutenh lagrave f(G N) Coacute 2 điểm mấu chốt của bagravei nagravey

Tiacutenh cost(i j) Tiacutenh nhanh bảng f(k i) Nếu tiacutenh trực tiếp theo cocircng thức trecircn ta mất độ phức tạp

O(GN^2) khocircng đủ để AC bagravei nagravey

1 Tiacutenh cost(i j) Với k = 1

Khi k = 1 điểm v chiacutenh lagrave median của datildey A(i)A(j) Do datildey A đatilde được sắp xếp tăng dần v = A[i + (j - i + 1) 2] Với mỗi (i j) ta coacute thể tiacutenh nhanh cost(i j) trong O(1) bằng mảng cộng dồn

Với k = 2

Đặt L = số phần tử của đoạn A(i)A(j) = j - i + 1 cost(i j) = sum( (a(s) - v)^2 )

= sum( a(s)^2 ) + Lv^2 + 2sum( a(s) )v Đặt B = 2sum( a(s) ) C = sum( a(s)^2 ) Ta tiacutenh được B vagrave C trong O(1) bằng mảng

cộng dồn cost(i j) = Lv^2 + Bv + C lagrave một hagravem bậc 2 của v Do đoacute điểm v để lagravem cost(i j) nhỏ

nhất chiacutenh lagrave v = -B L Tuy nhiecircn (-B L) coacute thể lagrave số thực cograven trong bagravei toaacuten nagravey v phải lagrave số nguyecircn necircn ta cần xeacutet 2 số nguyecircn v gần nhất với (-B L) bởi vigrave đồ thị hagravem số lồi

2 Tiacutenh f(k i) Để tiacutenh f(k i) ta cần dugraveng kĩ thuật QHĐ chia để trị Bạn coacute thể đọc lyacute thuyết ở VNOI wiki vagrave code ở đacircy Trong lời giải nagravey migravenh chỉ tập trung vagraveo việc chứng minh tiacutenh đuacuteng đắn của thuật toaacuten Nhắc lại ta coacute thể sử dụng được QHĐ chia để trị nếu

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 4: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

for (int j = i + 1 j lt= n j++)

result += f(i j)

3 Sau bước vừa rồi ta đatilde hoagraven toagraven loại bỏ khỏi result những datildey coacute chiacutenh xaacutec một hoặc hai phần tử xấu Giờ ta muốn loại bỏ khỏi result những datildey coacute chiacutenh xaacutec ba phần tử xấu Hatildey quan saacutet những datildey nagravey đatilde bị tiacutenh bao nhiecircu lần ở result trong ba bước trecircn Ở bước 0 mỗi datildey được cộng 1 lần Ở bước 1 mỗi datildey bị trừ 3 lần (Một datildey coacute ba vị triacute xấu

sẽ được tiacutenh trong ) Tới bước 2 mỗi datildey lại được cộng lại ba lần x y z (x) (y) (z)f f f (Một datildey coacute ba vị triacute xấu sẽ được tiacutenh trong ) Như vậy hiện tại x y z (x ) (y ) (z )f y f z f x mỗi datildey coacute chiacutenh xaacutec ba phần tử xấu hiện đang được tiacutenh 1 lần trong result Cocircng việc của ta bacircy giờ lagrave trừ noacute đi

for (int i = 1 i lt= n i++)

for (int j = i + 1 j lt= n j++)

for (int k = j + 1 k lt= n k++)

result -= f(i j k)

hellip Tiếp tục lập luận tương tự ta đi tới quy tắc tiacutenh sau đacircy Xeacutet mọi tập con A của

Nếu A coacute chẵn phần tử ta cộng thecircm vagraveo result Ngược lại nếu A coacute lẻ phần1 2 n (A)f tử ta trừ đi ở result (A)f

Dễ thấy giaacute trị của chỉ phụ thuộc vagraveo lực lượng của tập hợp A ta kyacute hiệu(A)f với tập hợp A tugravey yacute coacute K phần tử Thuật toaacuten chuẩn của bagravei toaacuten lagrave(k) (A)g = f

int result = 0

for (int k = 0 k lt= n k++)

int tmp = (k)Ckn times f

if (k 2 == 0) result += tmp else result -= tmp

Lời kết Trecircn đacircy lagrave phần trigravenh bagravey lời giải của migravenh Lời giải nagravey giagravenh phần lớn dung

lượng để giải thiacutech caacutech sử dụng nguyecircn lyacute bao hagravem loại trừ Với những bạn đatilde lagravem quen với nguyecircn lyacute nagravey từ lacircu caacutec bạn chỉ cần đọc lời giải đến phần Đếm số datildey nhị phacircn R bit 1 lagrave đủ Tuy nhiecircn coacute nhiều bạn ở Việt Nam dugrave học chuyecircn tin nhưng lại iacutet học toaacuten vagrave mới nghe qua khaacutei niệm nagravey lần đầu sẽ cảm thấy xa lạ với caacutech giải nagravey Cũng xin noacutei thecircm rằng caacutech suy luận migravenh đatilde trigravenh bagravey ở trecircn mang đậm tiacutenh suy luận trực giaacutec vagrave coacute phần thiếu chặt chẽ với mục điacutech giuacutep caacutec bạn iacutet tiếp xuacutec với toaacuten dễ cảm thụ hơn Dugrave migravenh đatilde chứng minh chặt chẽ được bằng toaacuten học mọi kết quả của bagravei toaacuten nagravey migravenh xin pheacutep khocircng trigravenh bagravey tại đacircy Hơn nữa ngagravey đầu tiecircn học nguyecircn lyacute bao hagravem vagrave loại trừ migravenh đatilde sử dụng caacutech suy luận ở trecircn để khiến những dograveng suy luận thecircm phần gần gũi

Lời giải 2 Nguyễn Đinh Quang Minh (team VNU - unsigned) Trước hết vigrave hai chồng rượu liecircn tiếp phải khaacutec magraveu nhau necircn ta coacute thể ldquotrảirdquo caacutec hộp rượu thagravenh hagraveng ngang Noacutei caacutech khaacutec mỗi cấu higravenh thỏa matilden tương đương với một caacutech xếp tất cả R + W hộp rượu thagravenh hagraveng ngang sao cho khocircng coacute d hộp rượu vang đỏ liecircn tiếp

Vigrave khocircng coacute ragraveng buộc nagraveo liecircn quan tới rượu trắng ta sẽ xacircy dựng một cấu higravenh thỏa matilden như sau

+ Đặt W hộp rượu trắng vagraveo trước tạo thagravenh W+1 ldquokhoảngrdquo để đặt rượu đỏ vagraveo + Đặt R hộp rượu đỏ vagraveo caacutec khoảng sao cho khocircng coacute khoảng nagraveo chứa nhiều hơn d

hộp Noacutei caacutech khaacutec nếu coi lagrave số hộp rượu đỏ nằm trong từng khoảng thigrave số cấu

higravenh thỏa matilden lagrave số bộ thỏa matilden vagrave

Xeacutet đa thức ta thấy hệ số chiacutenh lagrave số cấu higravenh thỏa matilden Biến đổi đa thức f

Theo khai triển Newton ta coacute

Aacutep dụng cocircng thức Taylor

Nhacircn vagraveo được

Thay ta được

Vậy

Ta coacute thể tiacutenh tổng trecircn trong độ phức tạp O(R+W)

B - Barcode (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Tổ hợp Tiacutenh nghịch đảo modulo Sagraveng số nguyecircn tố Ta xem một barcode tương đương một xacircu coacute độ dagravei N gồm caacutec kiacute tự lsquoBrsquo (magraveu xanh) hoặc lsquoRrsquo (magraveu đỏ) Gọi S 1 lagrave số chuỗi thỏa matilden yecircu cầu thứ nhất (số kiacute tự lsquoBrsquo bằng số kiacute tự lsquoRrsquo) S 2 lagrave số chuỗi thỏa matilden yecircu cầu thứ hai (khocircng coacute hai kiacute tự lsquoBrsquo liecircn tiếp) S 12 lagrave số chuỗi thỏa matilden cả hai yecircu cầu trecircn Đaacutep số bagravei toaacuten lagrave S 1 + S2 - S12

Tiacutenh S1 Nếu N lẻ hiển nhiecircn S 1 = 0 Ngược lại S 1 lagrave số caacutech chọn N2 vị triacute để gaacuten cho kiacute tự lsquoBrsquo trong số N vị triacute của xacircu Noacutei caacutech khaacutec S 1 = C(N N2) Tiacutenh S2 Gọi dp[i][0] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoBrsquo thỏa matilden yecircu cầu thứ hai dp[i][1] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoRrsquo thỏa matilden yecircu cầu thứ hai F[i] = dp[i][0]+dp[i][1] Ta coacute

dp[i][0] = dp[i-1][1] dp[i][1] = dp[i-1][0]+dp[i-1][1]

rArr F[i] = dp[i][0] + dp[i][1] = dp[i-1][1] + dp[i-1][0] + dp[i-1][1] = dp[i-2][0] + dp[i-2][1] + dp[i-1][0] + dp[i-1][1] = F[i-2] + F[i-1] Vậy F[i] chiacutenh lagrave số Fibonacci thứ i rArr S 2 chiacutenh lagrave số Fibonacci thứ N Tiacutenh S12 Nếu N lẻ hiển nhiecircn S 12 = 0 Ngược lại ta nhận xeacutet lagrave sẽ coacute khocircng quaacute 1 vị triacute coacute hai kiacute tự lsquoRrsquo liecircn tiếp nhau Ta coacute caacutec trường hợp sau

ldquoRBRBRBrdquo ldquoBRBRBRrdquo ldquoRBRBRRBRBRrdquo (coacute n2 - 1 xacircu)

Như vậy S 12 = n2 + 1 Vấn đề cograven lại lagrave tiacutenh C(N N2) modulo M Ta phacircn tiacutech C(N N2) thagravenh tiacutech caacutec thừa số nguyecircn tố C(N N2) = tiacutech(pi ^ ki) với pi lagrave số nguyecircn tố trong khoảng [1 N] Xeacutet lần lượt caacutec số nguyecircn tố trong khoảng [1 N] (coacute thể dugraveng sagraveng để liệt kecirc caacutec số nguyecircn tố) để tiacutenh ki ta lagravem như sau

Đặt f(N p) = x với x lagrave luỹ thừa lớn nhất của p magrave N chia hết cho p^x

Vigrave C(N N2) = N (N2) (N2) necircn ki = f(N p) - f(N2 p) - f(N2 p) Để tiacutenh f(N p) ta lần lượt đếm số lần xuất hiện của p trong khoảng [1 N] rồi đếm số lần

xuất hiện của p^2 trong khoảng [1 N] Ta coacute thể code đệ quy rất đơn giản như sau int f(int N int p) if (N lt p) return 0 return N p + f(Np p) Vigrave số lượng số nguyecircn tố trong khoảng [1 N] lagrave O(NlogN) vagrave độ phức tạp mỗi lần gọi f() lagrave O(logN) necircn ta coacute độ phức tạp với mỗi test lagrave O(N)

Lưu yacute Coacute rất nhiều team lagravem sai bagravei nagravey do tầng tầng lớp lớp caacutec bẫy magrave người ra đề đặt ra

Nếu ldquomắt nhanh hơn natildeordquo magrave nhigraven vagraveo test viacute dụ ta rất dễ lầm tưởng đaacutep aacuten lagrave số Fibonacci thứ n Điều nagravey chỉ đuacuteng với n lẻ (vagrave vocirc tigravenh đuacuteng với n = 2)

Trong quaacute trigravenh tiacutenh C(n n2) = thigrave cần chuacute yacute lagrave ta khocircng thể aacutep dụng cocircng thức a -1 equiv aM-2 (mod M) (hệ quả của Định liacute Euler ) được do với giới hạn M đề bagravei cho thigrave (n2) Vagrave M coacute thể khocircng nguyecircn tố cugraveng nhau Người ra đề cograven cố tigravenh cho dữ kiện M lagrave số nguyecircn tố nhằm gagravei bẫy caacutec thiacute sinh khocircng hiểu rotilde bản chất của định liacute Euler

Những bạn nagraveo bị sai lỗi nagravey hatildey đọc lại bagravei viết trecircn VNOI 10 lần Tiacutenh nghịch đảo modulo

C - Cu Chi Tunnel (1)

Taacutec giả Lecirc Đocircn Khuecirc

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Tham lam Ta sẽ tiến hagravenh gắn caacutec đỉnh vagraveo cacircy theo thứ tự từ 2 đến N Khi đoacute với đỉnh thứ i ta coacute thể gắn noacute vagraveo bất kigrave đỉnh nagraveo beacute hơn i magrave chưa đủ bậc Nếu tất cả caacutec đỉnh đều đatilde đủ bậc thigrave cacircu trả lời lagrave ldquoNOrdquo Cuối cugraveng nếu đatilde gắn xong đỉnh N magrave vẫn cograven đỉnh khocircng đủ bậc thigrave cũng in ra ldquoNOrdquo Viacute dụ 8

3 2 2 1 1 3 1 1

Đỉnh 2 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 1 1 0 0 0 0 0 0 Đỉnh 3 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 2 1 1 0 0 0 0 0 Đỉnh 4 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 3 1 1 1 0 0 0 0 Đỉnh 5 gắn với đỉnh 2 Mảng bậc hiện tại lagrave 3 2 1 1 1 0 0 0 Đỉnh 6 gắn với đỉnh 3 Mảng bậc hiện tại lagrave 3 2 2 1 1 1 0 0 Đỉnh 7 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 2 1 0 Đỉnh 8 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 3 1 1 Ta coacute thuật toaacuten độ phức tạp O(N^2) đủ để AC bagravei nagravey Nhưng ta coacute thể cải tiến thecircm bằng caacutech nhận xeacutet rằng ta chỉ cần quan tacircm đến tổng bậc cograven thiếu của caacutec đỉnh đatilde được gắn vagraveo cacircy magrave khocircng cần quan tacircm đến bậc cograven thiếu của từng đỉnh Do đoacute trong quaacute trigravenh duyệt ta chỉ cần lưu một biến cnt lagrave tổng bậc cograven thiếu hiện tại Độ phức tạp O(N)

D - Dropping Ball (4)

Taacutec giả Nguyễn Thagravenh Trung (RR)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned) Toacutem tắt đề bagravei Cho một bảng N x M với mỗi ocirc trong bảng coacute một trong 2 loại thanh lsquorsquo hoặc lsquorsquo Ta coacute Q truy vấn

- Đổi tường của một ocirc (ij) - Hỏi xem nếu thả một quả boacuteng vagraveo cột i thigrave quả boacuteng coacute thể xuống hagraveng cuối cugraveng rồi

ra khỏi bảng khocircng

Lời giải tracircu Để giải được toagraven bộ bagravei nagravey trước tiecircn ta phải nghĩ ra một lời giải tracircu nagraveo đoacute rồi tigravem caacutech cải tiến nếu coacute thể tuỳ vagraveo lời giải tracircu như nagraveo magrave cải tiến khaacutec nhau Coacute thể coi một ocirc (ij) bằng 2 nửa nửa trecircn vagrave nửa dưới Coi mỗi một nửa lagrave một đỉnh trecircn đồ thị Coacute thể dễ dagraveng nhận thấy mỗi một đỉnh nagravey chỉ coacute một đỉnh ra duy nhất tuỳ vagraveo loại thanh của caacutec ocirc xung quanh Nếu lagrave nửa dưới thigrave noacute chỉ coacute cạnh đi xuống dưới cograven nếu lagrave nửa trecircn thigrave noacute chỉ coacute cạnh đi sang một trong 2 ocirc becircn cạnh cugraveng hagraveng noacute Vậy với lời giải nagravey chỉ cần bfs lại toagraven bảng mỗi khi coacute truy vấn hỏi quả boacuteng đi đacircu

Lời giải tối ưu Lấy yacute tưởng bagravei httpcodeforcescomproblemsetproblem13E cugraveng với việc nhận ra N x M lt= 100 000 Migravenh đatilde coacute yacute tưởng chia bảng thagravenh những block caacutec hagraveng liecircn tiếp nhau mỗi block chứa xấp xỉ sqrt(N x M) ocirc Với mỗi block ta lưu lại được nếu thả quả boacuteng vagraveo cột j ở đầu block thigrave đến cuối block quả boacuteng sẽ ở cột nagraveo sử dụng lời giải tracircu ở trecircn Do vậy

- Truy vấn loại update ta thực hiện lại lời giải tracircu với tất cả caacutec ocirc thuộc block chứa ocirc (ij) cần update thực hiện lại việc bfs trecircn bảng Độ phức tạp thực hiện cocircng việc nagravey lagrave O(số ocirc của block) = O(sqrt(N x M)) Sau khi update với mỗi block ta coacute mảng nxt[j] = ocirc magrave quả boacuteng sẽ rơi xuống ở cuối block nếu quả boacuteng được thả ở cột j của block

- Truy vấn loại yecircu cầu trả lời Đi từ block 1 nhảy đến hagraveng đầu tiecircn của block 2 sử dụng thocircng tin trong block 1 tiếp tụchellip cho đến hết bảng Độ phức tạp (N x M (độ lớn mỗi block)) = O(sqrt(N x M))

Thế nhưng với trường hợp số hagraveng rất iacutet số cột rất to ta khocircng thể chia lagravem caacutec block sao cho mỗi block coacute iacutet hơn sqrt(N x M) phần tử được Do vậy với trường hợp N lt= sqrt(N x M) ta phải giải tracircu tức lagrave đi từ trecircn xuống dưới mỗi truy vấn mất đpt O(N) Thuật toaacuten nagravey bọn migravenh cảm thấy rất dễ code Với sự tinh tế của Nguyecircn team Unsigned đatilde hoagraven thagravenh việc code trong chỉ 15 phuacutet nộp phaacutet AC luocircn trong sự thăng hoa của team

E - Engaging with Loyal Customers (2) Thể loại Đồ thị Cặp gheacutep Lời giải Đacircy lagrave bagravei toaacuten cặp gheacutep coacute trọng số cực đại Để lagravem được bagravei nagravey caacutec bạn cần nắm vững Cặp gheacutep coacute trọng số trong saacutech thầy Lecirc Minh Hoagraveng (link) Cagravei đặt thuật toaacuten Hungary để giải Cặp gheacutep coacute trọng số code Một thuật toaacuten khaacutec cũng coacute thể dugraveng để giải cặp gheacutep coacute trọng số lagrave luồng mincost ( code) tuy nhiecircn khocircng thể chạy đủ nhanh vigrave đồ thị bagravei nagravey coacute 10^6 cạnh

F - Famous Pagoda (3)

Lời giải Nguyễn Thagravenh Trung - RR Thể loại Tối ưu hoaacute Quy hoạch động - Chia để trị Đặt cost(i j) lagrave chi phiacute để xacircy cầu thang từ điểm i đến j Đặt f(k i) = chi phiacute nhỏ nhất để k nhoacutem thợ xacircy tất cả cầu thang từ 1 đến i Ta coacute cocircng thức QHĐ

f(k i) = min( f(k-1 j) + cost(j+1 i) với j = 1i-1) Kết quả của bagravei toaacuten chiacutenh lagrave f(G N) Coacute 2 điểm mấu chốt của bagravei nagravey

Tiacutenh cost(i j) Tiacutenh nhanh bảng f(k i) Nếu tiacutenh trực tiếp theo cocircng thức trecircn ta mất độ phức tạp

O(GN^2) khocircng đủ để AC bagravei nagravey

1 Tiacutenh cost(i j) Với k = 1

Khi k = 1 điểm v chiacutenh lagrave median của datildey A(i)A(j) Do datildey A đatilde được sắp xếp tăng dần v = A[i + (j - i + 1) 2] Với mỗi (i j) ta coacute thể tiacutenh nhanh cost(i j) trong O(1) bằng mảng cộng dồn

Với k = 2

Đặt L = số phần tử của đoạn A(i)A(j) = j - i + 1 cost(i j) = sum( (a(s) - v)^2 )

= sum( a(s)^2 ) + Lv^2 + 2sum( a(s) )v Đặt B = 2sum( a(s) ) C = sum( a(s)^2 ) Ta tiacutenh được B vagrave C trong O(1) bằng mảng

cộng dồn cost(i j) = Lv^2 + Bv + C lagrave một hagravem bậc 2 của v Do đoacute điểm v để lagravem cost(i j) nhỏ

nhất chiacutenh lagrave v = -B L Tuy nhiecircn (-B L) coacute thể lagrave số thực cograven trong bagravei toaacuten nagravey v phải lagrave số nguyecircn necircn ta cần xeacutet 2 số nguyecircn v gần nhất với (-B L) bởi vigrave đồ thị hagravem số lồi

2 Tiacutenh f(k i) Để tiacutenh f(k i) ta cần dugraveng kĩ thuật QHĐ chia để trị Bạn coacute thể đọc lyacute thuyết ở VNOI wiki vagrave code ở đacircy Trong lời giải nagravey migravenh chỉ tập trung vagraveo việc chứng minh tiacutenh đuacuteng đắn của thuật toaacuten Nhắc lại ta coacute thể sử dụng được QHĐ chia để trị nếu

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 5: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

Vigrave khocircng coacute ragraveng buộc nagraveo liecircn quan tới rượu trắng ta sẽ xacircy dựng một cấu higravenh thỏa matilden như sau

+ Đặt W hộp rượu trắng vagraveo trước tạo thagravenh W+1 ldquokhoảngrdquo để đặt rượu đỏ vagraveo + Đặt R hộp rượu đỏ vagraveo caacutec khoảng sao cho khocircng coacute khoảng nagraveo chứa nhiều hơn d

hộp Noacutei caacutech khaacutec nếu coi lagrave số hộp rượu đỏ nằm trong từng khoảng thigrave số cấu

higravenh thỏa matilden lagrave số bộ thỏa matilden vagrave

Xeacutet đa thức ta thấy hệ số chiacutenh lagrave số cấu higravenh thỏa matilden Biến đổi đa thức f

Theo khai triển Newton ta coacute

Aacutep dụng cocircng thức Taylor

Nhacircn vagraveo được

Thay ta được

Vậy

Ta coacute thể tiacutenh tổng trecircn trong độ phức tạp O(R+W)

B - Barcode (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Tổ hợp Tiacutenh nghịch đảo modulo Sagraveng số nguyecircn tố Ta xem một barcode tương đương một xacircu coacute độ dagravei N gồm caacutec kiacute tự lsquoBrsquo (magraveu xanh) hoặc lsquoRrsquo (magraveu đỏ) Gọi S 1 lagrave số chuỗi thỏa matilden yecircu cầu thứ nhất (số kiacute tự lsquoBrsquo bằng số kiacute tự lsquoRrsquo) S 2 lagrave số chuỗi thỏa matilden yecircu cầu thứ hai (khocircng coacute hai kiacute tự lsquoBrsquo liecircn tiếp) S 12 lagrave số chuỗi thỏa matilden cả hai yecircu cầu trecircn Đaacutep số bagravei toaacuten lagrave S 1 + S2 - S12

Tiacutenh S1 Nếu N lẻ hiển nhiecircn S 1 = 0 Ngược lại S 1 lagrave số caacutech chọn N2 vị triacute để gaacuten cho kiacute tự lsquoBrsquo trong số N vị triacute của xacircu Noacutei caacutech khaacutec S 1 = C(N N2) Tiacutenh S2 Gọi dp[i][0] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoBrsquo thỏa matilden yecircu cầu thứ hai dp[i][1] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoRrsquo thỏa matilden yecircu cầu thứ hai F[i] = dp[i][0]+dp[i][1] Ta coacute

dp[i][0] = dp[i-1][1] dp[i][1] = dp[i-1][0]+dp[i-1][1]

rArr F[i] = dp[i][0] + dp[i][1] = dp[i-1][1] + dp[i-1][0] + dp[i-1][1] = dp[i-2][0] + dp[i-2][1] + dp[i-1][0] + dp[i-1][1] = F[i-2] + F[i-1] Vậy F[i] chiacutenh lagrave số Fibonacci thứ i rArr S 2 chiacutenh lagrave số Fibonacci thứ N Tiacutenh S12 Nếu N lẻ hiển nhiecircn S 12 = 0 Ngược lại ta nhận xeacutet lagrave sẽ coacute khocircng quaacute 1 vị triacute coacute hai kiacute tự lsquoRrsquo liecircn tiếp nhau Ta coacute caacutec trường hợp sau

ldquoRBRBRBrdquo ldquoBRBRBRrdquo ldquoRBRBRRBRBRrdquo (coacute n2 - 1 xacircu)

Như vậy S 12 = n2 + 1 Vấn đề cograven lại lagrave tiacutenh C(N N2) modulo M Ta phacircn tiacutech C(N N2) thagravenh tiacutech caacutec thừa số nguyecircn tố C(N N2) = tiacutech(pi ^ ki) với pi lagrave số nguyecircn tố trong khoảng [1 N] Xeacutet lần lượt caacutec số nguyecircn tố trong khoảng [1 N] (coacute thể dugraveng sagraveng để liệt kecirc caacutec số nguyecircn tố) để tiacutenh ki ta lagravem như sau

Đặt f(N p) = x với x lagrave luỹ thừa lớn nhất của p magrave N chia hết cho p^x

Vigrave C(N N2) = N (N2) (N2) necircn ki = f(N p) - f(N2 p) - f(N2 p) Để tiacutenh f(N p) ta lần lượt đếm số lần xuất hiện của p trong khoảng [1 N] rồi đếm số lần

xuất hiện của p^2 trong khoảng [1 N] Ta coacute thể code đệ quy rất đơn giản như sau int f(int N int p) if (N lt p) return 0 return N p + f(Np p) Vigrave số lượng số nguyecircn tố trong khoảng [1 N] lagrave O(NlogN) vagrave độ phức tạp mỗi lần gọi f() lagrave O(logN) necircn ta coacute độ phức tạp với mỗi test lagrave O(N)

Lưu yacute Coacute rất nhiều team lagravem sai bagravei nagravey do tầng tầng lớp lớp caacutec bẫy magrave người ra đề đặt ra

Nếu ldquomắt nhanh hơn natildeordquo magrave nhigraven vagraveo test viacute dụ ta rất dễ lầm tưởng đaacutep aacuten lagrave số Fibonacci thứ n Điều nagravey chỉ đuacuteng với n lẻ (vagrave vocirc tigravenh đuacuteng với n = 2)

Trong quaacute trigravenh tiacutenh C(n n2) = thigrave cần chuacute yacute lagrave ta khocircng thể aacutep dụng cocircng thức a -1 equiv aM-2 (mod M) (hệ quả của Định liacute Euler ) được do với giới hạn M đề bagravei cho thigrave (n2) Vagrave M coacute thể khocircng nguyecircn tố cugraveng nhau Người ra đề cograven cố tigravenh cho dữ kiện M lagrave số nguyecircn tố nhằm gagravei bẫy caacutec thiacute sinh khocircng hiểu rotilde bản chất của định liacute Euler

Những bạn nagraveo bị sai lỗi nagravey hatildey đọc lại bagravei viết trecircn VNOI 10 lần Tiacutenh nghịch đảo modulo

C - Cu Chi Tunnel (1)

Taacutec giả Lecirc Đocircn Khuecirc

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Tham lam Ta sẽ tiến hagravenh gắn caacutec đỉnh vagraveo cacircy theo thứ tự từ 2 đến N Khi đoacute với đỉnh thứ i ta coacute thể gắn noacute vagraveo bất kigrave đỉnh nagraveo beacute hơn i magrave chưa đủ bậc Nếu tất cả caacutec đỉnh đều đatilde đủ bậc thigrave cacircu trả lời lagrave ldquoNOrdquo Cuối cugraveng nếu đatilde gắn xong đỉnh N magrave vẫn cograven đỉnh khocircng đủ bậc thigrave cũng in ra ldquoNOrdquo Viacute dụ 8

3 2 2 1 1 3 1 1

Đỉnh 2 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 1 1 0 0 0 0 0 0 Đỉnh 3 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 2 1 1 0 0 0 0 0 Đỉnh 4 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 3 1 1 1 0 0 0 0 Đỉnh 5 gắn với đỉnh 2 Mảng bậc hiện tại lagrave 3 2 1 1 1 0 0 0 Đỉnh 6 gắn với đỉnh 3 Mảng bậc hiện tại lagrave 3 2 2 1 1 1 0 0 Đỉnh 7 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 2 1 0 Đỉnh 8 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 3 1 1 Ta coacute thuật toaacuten độ phức tạp O(N^2) đủ để AC bagravei nagravey Nhưng ta coacute thể cải tiến thecircm bằng caacutech nhận xeacutet rằng ta chỉ cần quan tacircm đến tổng bậc cograven thiếu của caacutec đỉnh đatilde được gắn vagraveo cacircy magrave khocircng cần quan tacircm đến bậc cograven thiếu của từng đỉnh Do đoacute trong quaacute trigravenh duyệt ta chỉ cần lưu một biến cnt lagrave tổng bậc cograven thiếu hiện tại Độ phức tạp O(N)

D - Dropping Ball (4)

Taacutec giả Nguyễn Thagravenh Trung (RR)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned) Toacutem tắt đề bagravei Cho một bảng N x M với mỗi ocirc trong bảng coacute một trong 2 loại thanh lsquorsquo hoặc lsquorsquo Ta coacute Q truy vấn

- Đổi tường của một ocirc (ij) - Hỏi xem nếu thả một quả boacuteng vagraveo cột i thigrave quả boacuteng coacute thể xuống hagraveng cuối cugraveng rồi

ra khỏi bảng khocircng

Lời giải tracircu Để giải được toagraven bộ bagravei nagravey trước tiecircn ta phải nghĩ ra một lời giải tracircu nagraveo đoacute rồi tigravem caacutech cải tiến nếu coacute thể tuỳ vagraveo lời giải tracircu như nagraveo magrave cải tiến khaacutec nhau Coacute thể coi một ocirc (ij) bằng 2 nửa nửa trecircn vagrave nửa dưới Coi mỗi một nửa lagrave một đỉnh trecircn đồ thị Coacute thể dễ dagraveng nhận thấy mỗi một đỉnh nagravey chỉ coacute một đỉnh ra duy nhất tuỳ vagraveo loại thanh của caacutec ocirc xung quanh Nếu lagrave nửa dưới thigrave noacute chỉ coacute cạnh đi xuống dưới cograven nếu lagrave nửa trecircn thigrave noacute chỉ coacute cạnh đi sang một trong 2 ocirc becircn cạnh cugraveng hagraveng noacute Vậy với lời giải nagravey chỉ cần bfs lại toagraven bảng mỗi khi coacute truy vấn hỏi quả boacuteng đi đacircu

Lời giải tối ưu Lấy yacute tưởng bagravei httpcodeforcescomproblemsetproblem13E cugraveng với việc nhận ra N x M lt= 100 000 Migravenh đatilde coacute yacute tưởng chia bảng thagravenh những block caacutec hagraveng liecircn tiếp nhau mỗi block chứa xấp xỉ sqrt(N x M) ocirc Với mỗi block ta lưu lại được nếu thả quả boacuteng vagraveo cột j ở đầu block thigrave đến cuối block quả boacuteng sẽ ở cột nagraveo sử dụng lời giải tracircu ở trecircn Do vậy

- Truy vấn loại update ta thực hiện lại lời giải tracircu với tất cả caacutec ocirc thuộc block chứa ocirc (ij) cần update thực hiện lại việc bfs trecircn bảng Độ phức tạp thực hiện cocircng việc nagravey lagrave O(số ocirc của block) = O(sqrt(N x M)) Sau khi update với mỗi block ta coacute mảng nxt[j] = ocirc magrave quả boacuteng sẽ rơi xuống ở cuối block nếu quả boacuteng được thả ở cột j của block

- Truy vấn loại yecircu cầu trả lời Đi từ block 1 nhảy đến hagraveng đầu tiecircn của block 2 sử dụng thocircng tin trong block 1 tiếp tụchellip cho đến hết bảng Độ phức tạp (N x M (độ lớn mỗi block)) = O(sqrt(N x M))

Thế nhưng với trường hợp số hagraveng rất iacutet số cột rất to ta khocircng thể chia lagravem caacutec block sao cho mỗi block coacute iacutet hơn sqrt(N x M) phần tử được Do vậy với trường hợp N lt= sqrt(N x M) ta phải giải tracircu tức lagrave đi từ trecircn xuống dưới mỗi truy vấn mất đpt O(N) Thuật toaacuten nagravey bọn migravenh cảm thấy rất dễ code Với sự tinh tế của Nguyecircn team Unsigned đatilde hoagraven thagravenh việc code trong chỉ 15 phuacutet nộp phaacutet AC luocircn trong sự thăng hoa của team

E - Engaging with Loyal Customers (2) Thể loại Đồ thị Cặp gheacutep Lời giải Đacircy lagrave bagravei toaacuten cặp gheacutep coacute trọng số cực đại Để lagravem được bagravei nagravey caacutec bạn cần nắm vững Cặp gheacutep coacute trọng số trong saacutech thầy Lecirc Minh Hoagraveng (link) Cagravei đặt thuật toaacuten Hungary để giải Cặp gheacutep coacute trọng số code Một thuật toaacuten khaacutec cũng coacute thể dugraveng để giải cặp gheacutep coacute trọng số lagrave luồng mincost ( code) tuy nhiecircn khocircng thể chạy đủ nhanh vigrave đồ thị bagravei nagravey coacute 10^6 cạnh

F - Famous Pagoda (3)

Lời giải Nguyễn Thagravenh Trung - RR Thể loại Tối ưu hoaacute Quy hoạch động - Chia để trị Đặt cost(i j) lagrave chi phiacute để xacircy cầu thang từ điểm i đến j Đặt f(k i) = chi phiacute nhỏ nhất để k nhoacutem thợ xacircy tất cả cầu thang từ 1 đến i Ta coacute cocircng thức QHĐ

f(k i) = min( f(k-1 j) + cost(j+1 i) với j = 1i-1) Kết quả của bagravei toaacuten chiacutenh lagrave f(G N) Coacute 2 điểm mấu chốt của bagravei nagravey

Tiacutenh cost(i j) Tiacutenh nhanh bảng f(k i) Nếu tiacutenh trực tiếp theo cocircng thức trecircn ta mất độ phức tạp

O(GN^2) khocircng đủ để AC bagravei nagravey

1 Tiacutenh cost(i j) Với k = 1

Khi k = 1 điểm v chiacutenh lagrave median của datildey A(i)A(j) Do datildey A đatilde được sắp xếp tăng dần v = A[i + (j - i + 1) 2] Với mỗi (i j) ta coacute thể tiacutenh nhanh cost(i j) trong O(1) bằng mảng cộng dồn

Với k = 2

Đặt L = số phần tử của đoạn A(i)A(j) = j - i + 1 cost(i j) = sum( (a(s) - v)^2 )

= sum( a(s)^2 ) + Lv^2 + 2sum( a(s) )v Đặt B = 2sum( a(s) ) C = sum( a(s)^2 ) Ta tiacutenh được B vagrave C trong O(1) bằng mảng

cộng dồn cost(i j) = Lv^2 + Bv + C lagrave một hagravem bậc 2 của v Do đoacute điểm v để lagravem cost(i j) nhỏ

nhất chiacutenh lagrave v = -B L Tuy nhiecircn (-B L) coacute thể lagrave số thực cograven trong bagravei toaacuten nagravey v phải lagrave số nguyecircn necircn ta cần xeacutet 2 số nguyecircn v gần nhất với (-B L) bởi vigrave đồ thị hagravem số lồi

2 Tiacutenh f(k i) Để tiacutenh f(k i) ta cần dugraveng kĩ thuật QHĐ chia để trị Bạn coacute thể đọc lyacute thuyết ở VNOI wiki vagrave code ở đacircy Trong lời giải nagravey migravenh chỉ tập trung vagraveo việc chứng minh tiacutenh đuacuteng đắn của thuật toaacuten Nhắc lại ta coacute thể sử dụng được QHĐ chia để trị nếu

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 6: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

Ta coacute thể tiacutenh tổng trecircn trong độ phức tạp O(R+W)

B - Barcode (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Tổ hợp Tiacutenh nghịch đảo modulo Sagraveng số nguyecircn tố Ta xem một barcode tương đương một xacircu coacute độ dagravei N gồm caacutec kiacute tự lsquoBrsquo (magraveu xanh) hoặc lsquoRrsquo (magraveu đỏ) Gọi S 1 lagrave số chuỗi thỏa matilden yecircu cầu thứ nhất (số kiacute tự lsquoBrsquo bằng số kiacute tự lsquoRrsquo) S 2 lagrave số chuỗi thỏa matilden yecircu cầu thứ hai (khocircng coacute hai kiacute tự lsquoBrsquo liecircn tiếp) S 12 lagrave số chuỗi thỏa matilden cả hai yecircu cầu trecircn Đaacutep số bagravei toaacuten lagrave S 1 + S2 - S12

Tiacutenh S1 Nếu N lẻ hiển nhiecircn S 1 = 0 Ngược lại S 1 lagrave số caacutech chọn N2 vị triacute để gaacuten cho kiacute tự lsquoBrsquo trong số N vị triacute của xacircu Noacutei caacutech khaacutec S 1 = C(N N2) Tiacutenh S2 Gọi dp[i][0] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoBrsquo thỏa matilden yecircu cầu thứ hai dp[i][1] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoRrsquo thỏa matilden yecircu cầu thứ hai F[i] = dp[i][0]+dp[i][1] Ta coacute

dp[i][0] = dp[i-1][1] dp[i][1] = dp[i-1][0]+dp[i-1][1]

rArr F[i] = dp[i][0] + dp[i][1] = dp[i-1][1] + dp[i-1][0] + dp[i-1][1] = dp[i-2][0] + dp[i-2][1] + dp[i-1][0] + dp[i-1][1] = F[i-2] + F[i-1] Vậy F[i] chiacutenh lagrave số Fibonacci thứ i rArr S 2 chiacutenh lagrave số Fibonacci thứ N Tiacutenh S12 Nếu N lẻ hiển nhiecircn S 12 = 0 Ngược lại ta nhận xeacutet lagrave sẽ coacute khocircng quaacute 1 vị triacute coacute hai kiacute tự lsquoRrsquo liecircn tiếp nhau Ta coacute caacutec trường hợp sau

ldquoRBRBRBrdquo ldquoBRBRBRrdquo ldquoRBRBRRBRBRrdquo (coacute n2 - 1 xacircu)

Như vậy S 12 = n2 + 1 Vấn đề cograven lại lagrave tiacutenh C(N N2) modulo M Ta phacircn tiacutech C(N N2) thagravenh tiacutech caacutec thừa số nguyecircn tố C(N N2) = tiacutech(pi ^ ki) với pi lagrave số nguyecircn tố trong khoảng [1 N] Xeacutet lần lượt caacutec số nguyecircn tố trong khoảng [1 N] (coacute thể dugraveng sagraveng để liệt kecirc caacutec số nguyecircn tố) để tiacutenh ki ta lagravem như sau

Đặt f(N p) = x với x lagrave luỹ thừa lớn nhất của p magrave N chia hết cho p^x

Vigrave C(N N2) = N (N2) (N2) necircn ki = f(N p) - f(N2 p) - f(N2 p) Để tiacutenh f(N p) ta lần lượt đếm số lần xuất hiện của p trong khoảng [1 N] rồi đếm số lần

xuất hiện của p^2 trong khoảng [1 N] Ta coacute thể code đệ quy rất đơn giản như sau int f(int N int p) if (N lt p) return 0 return N p + f(Np p) Vigrave số lượng số nguyecircn tố trong khoảng [1 N] lagrave O(NlogN) vagrave độ phức tạp mỗi lần gọi f() lagrave O(logN) necircn ta coacute độ phức tạp với mỗi test lagrave O(N)

Lưu yacute Coacute rất nhiều team lagravem sai bagravei nagravey do tầng tầng lớp lớp caacutec bẫy magrave người ra đề đặt ra

Nếu ldquomắt nhanh hơn natildeordquo magrave nhigraven vagraveo test viacute dụ ta rất dễ lầm tưởng đaacutep aacuten lagrave số Fibonacci thứ n Điều nagravey chỉ đuacuteng với n lẻ (vagrave vocirc tigravenh đuacuteng với n = 2)

Trong quaacute trigravenh tiacutenh C(n n2) = thigrave cần chuacute yacute lagrave ta khocircng thể aacutep dụng cocircng thức a -1 equiv aM-2 (mod M) (hệ quả của Định liacute Euler ) được do với giới hạn M đề bagravei cho thigrave (n2) Vagrave M coacute thể khocircng nguyecircn tố cugraveng nhau Người ra đề cograven cố tigravenh cho dữ kiện M lagrave số nguyecircn tố nhằm gagravei bẫy caacutec thiacute sinh khocircng hiểu rotilde bản chất của định liacute Euler

Những bạn nagraveo bị sai lỗi nagravey hatildey đọc lại bagravei viết trecircn VNOI 10 lần Tiacutenh nghịch đảo modulo

C - Cu Chi Tunnel (1)

Taacutec giả Lecirc Đocircn Khuecirc

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Tham lam Ta sẽ tiến hagravenh gắn caacutec đỉnh vagraveo cacircy theo thứ tự từ 2 đến N Khi đoacute với đỉnh thứ i ta coacute thể gắn noacute vagraveo bất kigrave đỉnh nagraveo beacute hơn i magrave chưa đủ bậc Nếu tất cả caacutec đỉnh đều đatilde đủ bậc thigrave cacircu trả lời lagrave ldquoNOrdquo Cuối cugraveng nếu đatilde gắn xong đỉnh N magrave vẫn cograven đỉnh khocircng đủ bậc thigrave cũng in ra ldquoNOrdquo Viacute dụ 8

3 2 2 1 1 3 1 1

Đỉnh 2 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 1 1 0 0 0 0 0 0 Đỉnh 3 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 2 1 1 0 0 0 0 0 Đỉnh 4 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 3 1 1 1 0 0 0 0 Đỉnh 5 gắn với đỉnh 2 Mảng bậc hiện tại lagrave 3 2 1 1 1 0 0 0 Đỉnh 6 gắn với đỉnh 3 Mảng bậc hiện tại lagrave 3 2 2 1 1 1 0 0 Đỉnh 7 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 2 1 0 Đỉnh 8 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 3 1 1 Ta coacute thuật toaacuten độ phức tạp O(N^2) đủ để AC bagravei nagravey Nhưng ta coacute thể cải tiến thecircm bằng caacutech nhận xeacutet rằng ta chỉ cần quan tacircm đến tổng bậc cograven thiếu của caacutec đỉnh đatilde được gắn vagraveo cacircy magrave khocircng cần quan tacircm đến bậc cograven thiếu của từng đỉnh Do đoacute trong quaacute trigravenh duyệt ta chỉ cần lưu một biến cnt lagrave tổng bậc cograven thiếu hiện tại Độ phức tạp O(N)

D - Dropping Ball (4)

Taacutec giả Nguyễn Thagravenh Trung (RR)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned) Toacutem tắt đề bagravei Cho một bảng N x M với mỗi ocirc trong bảng coacute một trong 2 loại thanh lsquorsquo hoặc lsquorsquo Ta coacute Q truy vấn

- Đổi tường của một ocirc (ij) - Hỏi xem nếu thả một quả boacuteng vagraveo cột i thigrave quả boacuteng coacute thể xuống hagraveng cuối cugraveng rồi

ra khỏi bảng khocircng

Lời giải tracircu Để giải được toagraven bộ bagravei nagravey trước tiecircn ta phải nghĩ ra một lời giải tracircu nagraveo đoacute rồi tigravem caacutech cải tiến nếu coacute thể tuỳ vagraveo lời giải tracircu như nagraveo magrave cải tiến khaacutec nhau Coacute thể coi một ocirc (ij) bằng 2 nửa nửa trecircn vagrave nửa dưới Coi mỗi một nửa lagrave một đỉnh trecircn đồ thị Coacute thể dễ dagraveng nhận thấy mỗi một đỉnh nagravey chỉ coacute một đỉnh ra duy nhất tuỳ vagraveo loại thanh của caacutec ocirc xung quanh Nếu lagrave nửa dưới thigrave noacute chỉ coacute cạnh đi xuống dưới cograven nếu lagrave nửa trecircn thigrave noacute chỉ coacute cạnh đi sang một trong 2 ocirc becircn cạnh cugraveng hagraveng noacute Vậy với lời giải nagravey chỉ cần bfs lại toagraven bảng mỗi khi coacute truy vấn hỏi quả boacuteng đi đacircu

Lời giải tối ưu Lấy yacute tưởng bagravei httpcodeforcescomproblemsetproblem13E cugraveng với việc nhận ra N x M lt= 100 000 Migravenh đatilde coacute yacute tưởng chia bảng thagravenh những block caacutec hagraveng liecircn tiếp nhau mỗi block chứa xấp xỉ sqrt(N x M) ocirc Với mỗi block ta lưu lại được nếu thả quả boacuteng vagraveo cột j ở đầu block thigrave đến cuối block quả boacuteng sẽ ở cột nagraveo sử dụng lời giải tracircu ở trecircn Do vậy

- Truy vấn loại update ta thực hiện lại lời giải tracircu với tất cả caacutec ocirc thuộc block chứa ocirc (ij) cần update thực hiện lại việc bfs trecircn bảng Độ phức tạp thực hiện cocircng việc nagravey lagrave O(số ocirc của block) = O(sqrt(N x M)) Sau khi update với mỗi block ta coacute mảng nxt[j] = ocirc magrave quả boacuteng sẽ rơi xuống ở cuối block nếu quả boacuteng được thả ở cột j của block

- Truy vấn loại yecircu cầu trả lời Đi từ block 1 nhảy đến hagraveng đầu tiecircn của block 2 sử dụng thocircng tin trong block 1 tiếp tụchellip cho đến hết bảng Độ phức tạp (N x M (độ lớn mỗi block)) = O(sqrt(N x M))

Thế nhưng với trường hợp số hagraveng rất iacutet số cột rất to ta khocircng thể chia lagravem caacutec block sao cho mỗi block coacute iacutet hơn sqrt(N x M) phần tử được Do vậy với trường hợp N lt= sqrt(N x M) ta phải giải tracircu tức lagrave đi từ trecircn xuống dưới mỗi truy vấn mất đpt O(N) Thuật toaacuten nagravey bọn migravenh cảm thấy rất dễ code Với sự tinh tế của Nguyecircn team Unsigned đatilde hoagraven thagravenh việc code trong chỉ 15 phuacutet nộp phaacutet AC luocircn trong sự thăng hoa của team

E - Engaging with Loyal Customers (2) Thể loại Đồ thị Cặp gheacutep Lời giải Đacircy lagrave bagravei toaacuten cặp gheacutep coacute trọng số cực đại Để lagravem được bagravei nagravey caacutec bạn cần nắm vững Cặp gheacutep coacute trọng số trong saacutech thầy Lecirc Minh Hoagraveng (link) Cagravei đặt thuật toaacuten Hungary để giải Cặp gheacutep coacute trọng số code Một thuật toaacuten khaacutec cũng coacute thể dugraveng để giải cặp gheacutep coacute trọng số lagrave luồng mincost ( code) tuy nhiecircn khocircng thể chạy đủ nhanh vigrave đồ thị bagravei nagravey coacute 10^6 cạnh

F - Famous Pagoda (3)

Lời giải Nguyễn Thagravenh Trung - RR Thể loại Tối ưu hoaacute Quy hoạch động - Chia để trị Đặt cost(i j) lagrave chi phiacute để xacircy cầu thang từ điểm i đến j Đặt f(k i) = chi phiacute nhỏ nhất để k nhoacutem thợ xacircy tất cả cầu thang từ 1 đến i Ta coacute cocircng thức QHĐ

f(k i) = min( f(k-1 j) + cost(j+1 i) với j = 1i-1) Kết quả của bagravei toaacuten chiacutenh lagrave f(G N) Coacute 2 điểm mấu chốt của bagravei nagravey

Tiacutenh cost(i j) Tiacutenh nhanh bảng f(k i) Nếu tiacutenh trực tiếp theo cocircng thức trecircn ta mất độ phức tạp

O(GN^2) khocircng đủ để AC bagravei nagravey

1 Tiacutenh cost(i j) Với k = 1

Khi k = 1 điểm v chiacutenh lagrave median của datildey A(i)A(j) Do datildey A đatilde được sắp xếp tăng dần v = A[i + (j - i + 1) 2] Với mỗi (i j) ta coacute thể tiacutenh nhanh cost(i j) trong O(1) bằng mảng cộng dồn

Với k = 2

Đặt L = số phần tử của đoạn A(i)A(j) = j - i + 1 cost(i j) = sum( (a(s) - v)^2 )

= sum( a(s)^2 ) + Lv^2 + 2sum( a(s) )v Đặt B = 2sum( a(s) ) C = sum( a(s)^2 ) Ta tiacutenh được B vagrave C trong O(1) bằng mảng

cộng dồn cost(i j) = Lv^2 + Bv + C lagrave một hagravem bậc 2 của v Do đoacute điểm v để lagravem cost(i j) nhỏ

nhất chiacutenh lagrave v = -B L Tuy nhiecircn (-B L) coacute thể lagrave số thực cograven trong bagravei toaacuten nagravey v phải lagrave số nguyecircn necircn ta cần xeacutet 2 số nguyecircn v gần nhất với (-B L) bởi vigrave đồ thị hagravem số lồi

2 Tiacutenh f(k i) Để tiacutenh f(k i) ta cần dugraveng kĩ thuật QHĐ chia để trị Bạn coacute thể đọc lyacute thuyết ở VNOI wiki vagrave code ở đacircy Trong lời giải nagravey migravenh chỉ tập trung vagraveo việc chứng minh tiacutenh đuacuteng đắn của thuật toaacuten Nhắc lại ta coacute thể sử dụng được QHĐ chia để trị nếu

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 7: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

B - Barcode (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Tổ hợp Tiacutenh nghịch đảo modulo Sagraveng số nguyecircn tố Ta xem một barcode tương đương một xacircu coacute độ dagravei N gồm caacutec kiacute tự lsquoBrsquo (magraveu xanh) hoặc lsquoRrsquo (magraveu đỏ) Gọi S 1 lagrave số chuỗi thỏa matilden yecircu cầu thứ nhất (số kiacute tự lsquoBrsquo bằng số kiacute tự lsquoRrsquo) S 2 lagrave số chuỗi thỏa matilden yecircu cầu thứ hai (khocircng coacute hai kiacute tự lsquoBrsquo liecircn tiếp) S 12 lagrave số chuỗi thỏa matilden cả hai yecircu cầu trecircn Đaacutep số bagravei toaacuten lagrave S 1 + S2 - S12

Tiacutenh S1 Nếu N lẻ hiển nhiecircn S 1 = 0 Ngược lại S 1 lagrave số caacutech chọn N2 vị triacute để gaacuten cho kiacute tự lsquoBrsquo trong số N vị triacute của xacircu Noacutei caacutech khaacutec S 1 = C(N N2) Tiacutenh S2 Gọi dp[i][0] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoBrsquo thỏa matilden yecircu cầu thứ hai dp[i][1] lagrave số lượng xacircu độ dagravei i kết thuacutec bởi kiacute tự lsquoRrsquo thỏa matilden yecircu cầu thứ hai F[i] = dp[i][0]+dp[i][1] Ta coacute

dp[i][0] = dp[i-1][1] dp[i][1] = dp[i-1][0]+dp[i-1][1]

rArr F[i] = dp[i][0] + dp[i][1] = dp[i-1][1] + dp[i-1][0] + dp[i-1][1] = dp[i-2][0] + dp[i-2][1] + dp[i-1][0] + dp[i-1][1] = F[i-2] + F[i-1] Vậy F[i] chiacutenh lagrave số Fibonacci thứ i rArr S 2 chiacutenh lagrave số Fibonacci thứ N Tiacutenh S12 Nếu N lẻ hiển nhiecircn S 12 = 0 Ngược lại ta nhận xeacutet lagrave sẽ coacute khocircng quaacute 1 vị triacute coacute hai kiacute tự lsquoRrsquo liecircn tiếp nhau Ta coacute caacutec trường hợp sau

ldquoRBRBRBrdquo ldquoBRBRBRrdquo ldquoRBRBRRBRBRrdquo (coacute n2 - 1 xacircu)

Như vậy S 12 = n2 + 1 Vấn đề cograven lại lagrave tiacutenh C(N N2) modulo M Ta phacircn tiacutech C(N N2) thagravenh tiacutech caacutec thừa số nguyecircn tố C(N N2) = tiacutech(pi ^ ki) với pi lagrave số nguyecircn tố trong khoảng [1 N] Xeacutet lần lượt caacutec số nguyecircn tố trong khoảng [1 N] (coacute thể dugraveng sagraveng để liệt kecirc caacutec số nguyecircn tố) để tiacutenh ki ta lagravem như sau

Đặt f(N p) = x với x lagrave luỹ thừa lớn nhất của p magrave N chia hết cho p^x

Vigrave C(N N2) = N (N2) (N2) necircn ki = f(N p) - f(N2 p) - f(N2 p) Để tiacutenh f(N p) ta lần lượt đếm số lần xuất hiện của p trong khoảng [1 N] rồi đếm số lần

xuất hiện của p^2 trong khoảng [1 N] Ta coacute thể code đệ quy rất đơn giản như sau int f(int N int p) if (N lt p) return 0 return N p + f(Np p) Vigrave số lượng số nguyecircn tố trong khoảng [1 N] lagrave O(NlogN) vagrave độ phức tạp mỗi lần gọi f() lagrave O(logN) necircn ta coacute độ phức tạp với mỗi test lagrave O(N)

Lưu yacute Coacute rất nhiều team lagravem sai bagravei nagravey do tầng tầng lớp lớp caacutec bẫy magrave người ra đề đặt ra

Nếu ldquomắt nhanh hơn natildeordquo magrave nhigraven vagraveo test viacute dụ ta rất dễ lầm tưởng đaacutep aacuten lagrave số Fibonacci thứ n Điều nagravey chỉ đuacuteng với n lẻ (vagrave vocirc tigravenh đuacuteng với n = 2)

Trong quaacute trigravenh tiacutenh C(n n2) = thigrave cần chuacute yacute lagrave ta khocircng thể aacutep dụng cocircng thức a -1 equiv aM-2 (mod M) (hệ quả của Định liacute Euler ) được do với giới hạn M đề bagravei cho thigrave (n2) Vagrave M coacute thể khocircng nguyecircn tố cugraveng nhau Người ra đề cograven cố tigravenh cho dữ kiện M lagrave số nguyecircn tố nhằm gagravei bẫy caacutec thiacute sinh khocircng hiểu rotilde bản chất của định liacute Euler

Những bạn nagraveo bị sai lỗi nagravey hatildey đọc lại bagravei viết trecircn VNOI 10 lần Tiacutenh nghịch đảo modulo

C - Cu Chi Tunnel (1)

Taacutec giả Lecirc Đocircn Khuecirc

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Tham lam Ta sẽ tiến hagravenh gắn caacutec đỉnh vagraveo cacircy theo thứ tự từ 2 đến N Khi đoacute với đỉnh thứ i ta coacute thể gắn noacute vagraveo bất kigrave đỉnh nagraveo beacute hơn i magrave chưa đủ bậc Nếu tất cả caacutec đỉnh đều đatilde đủ bậc thigrave cacircu trả lời lagrave ldquoNOrdquo Cuối cugraveng nếu đatilde gắn xong đỉnh N magrave vẫn cograven đỉnh khocircng đủ bậc thigrave cũng in ra ldquoNOrdquo Viacute dụ 8

3 2 2 1 1 3 1 1

Đỉnh 2 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 1 1 0 0 0 0 0 0 Đỉnh 3 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 2 1 1 0 0 0 0 0 Đỉnh 4 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 3 1 1 1 0 0 0 0 Đỉnh 5 gắn với đỉnh 2 Mảng bậc hiện tại lagrave 3 2 1 1 1 0 0 0 Đỉnh 6 gắn với đỉnh 3 Mảng bậc hiện tại lagrave 3 2 2 1 1 1 0 0 Đỉnh 7 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 2 1 0 Đỉnh 8 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 3 1 1 Ta coacute thuật toaacuten độ phức tạp O(N^2) đủ để AC bagravei nagravey Nhưng ta coacute thể cải tiến thecircm bằng caacutech nhận xeacutet rằng ta chỉ cần quan tacircm đến tổng bậc cograven thiếu của caacutec đỉnh đatilde được gắn vagraveo cacircy magrave khocircng cần quan tacircm đến bậc cograven thiếu của từng đỉnh Do đoacute trong quaacute trigravenh duyệt ta chỉ cần lưu một biến cnt lagrave tổng bậc cograven thiếu hiện tại Độ phức tạp O(N)

D - Dropping Ball (4)

Taacutec giả Nguyễn Thagravenh Trung (RR)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned) Toacutem tắt đề bagravei Cho một bảng N x M với mỗi ocirc trong bảng coacute một trong 2 loại thanh lsquorsquo hoặc lsquorsquo Ta coacute Q truy vấn

- Đổi tường của một ocirc (ij) - Hỏi xem nếu thả một quả boacuteng vagraveo cột i thigrave quả boacuteng coacute thể xuống hagraveng cuối cugraveng rồi

ra khỏi bảng khocircng

Lời giải tracircu Để giải được toagraven bộ bagravei nagravey trước tiecircn ta phải nghĩ ra một lời giải tracircu nagraveo đoacute rồi tigravem caacutech cải tiến nếu coacute thể tuỳ vagraveo lời giải tracircu như nagraveo magrave cải tiến khaacutec nhau Coacute thể coi một ocirc (ij) bằng 2 nửa nửa trecircn vagrave nửa dưới Coi mỗi một nửa lagrave một đỉnh trecircn đồ thị Coacute thể dễ dagraveng nhận thấy mỗi một đỉnh nagravey chỉ coacute một đỉnh ra duy nhất tuỳ vagraveo loại thanh của caacutec ocirc xung quanh Nếu lagrave nửa dưới thigrave noacute chỉ coacute cạnh đi xuống dưới cograven nếu lagrave nửa trecircn thigrave noacute chỉ coacute cạnh đi sang một trong 2 ocirc becircn cạnh cugraveng hagraveng noacute Vậy với lời giải nagravey chỉ cần bfs lại toagraven bảng mỗi khi coacute truy vấn hỏi quả boacuteng đi đacircu

Lời giải tối ưu Lấy yacute tưởng bagravei httpcodeforcescomproblemsetproblem13E cugraveng với việc nhận ra N x M lt= 100 000 Migravenh đatilde coacute yacute tưởng chia bảng thagravenh những block caacutec hagraveng liecircn tiếp nhau mỗi block chứa xấp xỉ sqrt(N x M) ocirc Với mỗi block ta lưu lại được nếu thả quả boacuteng vagraveo cột j ở đầu block thigrave đến cuối block quả boacuteng sẽ ở cột nagraveo sử dụng lời giải tracircu ở trecircn Do vậy

- Truy vấn loại update ta thực hiện lại lời giải tracircu với tất cả caacutec ocirc thuộc block chứa ocirc (ij) cần update thực hiện lại việc bfs trecircn bảng Độ phức tạp thực hiện cocircng việc nagravey lagrave O(số ocirc của block) = O(sqrt(N x M)) Sau khi update với mỗi block ta coacute mảng nxt[j] = ocirc magrave quả boacuteng sẽ rơi xuống ở cuối block nếu quả boacuteng được thả ở cột j của block

- Truy vấn loại yecircu cầu trả lời Đi từ block 1 nhảy đến hagraveng đầu tiecircn của block 2 sử dụng thocircng tin trong block 1 tiếp tụchellip cho đến hết bảng Độ phức tạp (N x M (độ lớn mỗi block)) = O(sqrt(N x M))

Thế nhưng với trường hợp số hagraveng rất iacutet số cột rất to ta khocircng thể chia lagravem caacutec block sao cho mỗi block coacute iacutet hơn sqrt(N x M) phần tử được Do vậy với trường hợp N lt= sqrt(N x M) ta phải giải tracircu tức lagrave đi từ trecircn xuống dưới mỗi truy vấn mất đpt O(N) Thuật toaacuten nagravey bọn migravenh cảm thấy rất dễ code Với sự tinh tế của Nguyecircn team Unsigned đatilde hoagraven thagravenh việc code trong chỉ 15 phuacutet nộp phaacutet AC luocircn trong sự thăng hoa của team

E - Engaging with Loyal Customers (2) Thể loại Đồ thị Cặp gheacutep Lời giải Đacircy lagrave bagravei toaacuten cặp gheacutep coacute trọng số cực đại Để lagravem được bagravei nagravey caacutec bạn cần nắm vững Cặp gheacutep coacute trọng số trong saacutech thầy Lecirc Minh Hoagraveng (link) Cagravei đặt thuật toaacuten Hungary để giải Cặp gheacutep coacute trọng số code Một thuật toaacuten khaacutec cũng coacute thể dugraveng để giải cặp gheacutep coacute trọng số lagrave luồng mincost ( code) tuy nhiecircn khocircng thể chạy đủ nhanh vigrave đồ thị bagravei nagravey coacute 10^6 cạnh

F - Famous Pagoda (3)

Lời giải Nguyễn Thagravenh Trung - RR Thể loại Tối ưu hoaacute Quy hoạch động - Chia để trị Đặt cost(i j) lagrave chi phiacute để xacircy cầu thang từ điểm i đến j Đặt f(k i) = chi phiacute nhỏ nhất để k nhoacutem thợ xacircy tất cả cầu thang từ 1 đến i Ta coacute cocircng thức QHĐ

f(k i) = min( f(k-1 j) + cost(j+1 i) với j = 1i-1) Kết quả của bagravei toaacuten chiacutenh lagrave f(G N) Coacute 2 điểm mấu chốt của bagravei nagravey

Tiacutenh cost(i j) Tiacutenh nhanh bảng f(k i) Nếu tiacutenh trực tiếp theo cocircng thức trecircn ta mất độ phức tạp

O(GN^2) khocircng đủ để AC bagravei nagravey

1 Tiacutenh cost(i j) Với k = 1

Khi k = 1 điểm v chiacutenh lagrave median của datildey A(i)A(j) Do datildey A đatilde được sắp xếp tăng dần v = A[i + (j - i + 1) 2] Với mỗi (i j) ta coacute thể tiacutenh nhanh cost(i j) trong O(1) bằng mảng cộng dồn

Với k = 2

Đặt L = số phần tử của đoạn A(i)A(j) = j - i + 1 cost(i j) = sum( (a(s) - v)^2 )

= sum( a(s)^2 ) + Lv^2 + 2sum( a(s) )v Đặt B = 2sum( a(s) ) C = sum( a(s)^2 ) Ta tiacutenh được B vagrave C trong O(1) bằng mảng

cộng dồn cost(i j) = Lv^2 + Bv + C lagrave một hagravem bậc 2 của v Do đoacute điểm v để lagravem cost(i j) nhỏ

nhất chiacutenh lagrave v = -B L Tuy nhiecircn (-B L) coacute thể lagrave số thực cograven trong bagravei toaacuten nagravey v phải lagrave số nguyecircn necircn ta cần xeacutet 2 số nguyecircn v gần nhất với (-B L) bởi vigrave đồ thị hagravem số lồi

2 Tiacutenh f(k i) Để tiacutenh f(k i) ta cần dugraveng kĩ thuật QHĐ chia để trị Bạn coacute thể đọc lyacute thuyết ở VNOI wiki vagrave code ở đacircy Trong lời giải nagravey migravenh chỉ tập trung vagraveo việc chứng minh tiacutenh đuacuteng đắn của thuật toaacuten Nhắc lại ta coacute thể sử dụng được QHĐ chia để trị nếu

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 8: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

Vigrave C(N N2) = N (N2) (N2) necircn ki = f(N p) - f(N2 p) - f(N2 p) Để tiacutenh f(N p) ta lần lượt đếm số lần xuất hiện của p trong khoảng [1 N] rồi đếm số lần

xuất hiện của p^2 trong khoảng [1 N] Ta coacute thể code đệ quy rất đơn giản như sau int f(int N int p) if (N lt p) return 0 return N p + f(Np p) Vigrave số lượng số nguyecircn tố trong khoảng [1 N] lagrave O(NlogN) vagrave độ phức tạp mỗi lần gọi f() lagrave O(logN) necircn ta coacute độ phức tạp với mỗi test lagrave O(N)

Lưu yacute Coacute rất nhiều team lagravem sai bagravei nagravey do tầng tầng lớp lớp caacutec bẫy magrave người ra đề đặt ra

Nếu ldquomắt nhanh hơn natildeordquo magrave nhigraven vagraveo test viacute dụ ta rất dễ lầm tưởng đaacutep aacuten lagrave số Fibonacci thứ n Điều nagravey chỉ đuacuteng với n lẻ (vagrave vocirc tigravenh đuacuteng với n = 2)

Trong quaacute trigravenh tiacutenh C(n n2) = thigrave cần chuacute yacute lagrave ta khocircng thể aacutep dụng cocircng thức a -1 equiv aM-2 (mod M) (hệ quả của Định liacute Euler ) được do với giới hạn M đề bagravei cho thigrave (n2) Vagrave M coacute thể khocircng nguyecircn tố cugraveng nhau Người ra đề cograven cố tigravenh cho dữ kiện M lagrave số nguyecircn tố nhằm gagravei bẫy caacutec thiacute sinh khocircng hiểu rotilde bản chất của định liacute Euler

Những bạn nagraveo bị sai lỗi nagravey hatildey đọc lại bagravei viết trecircn VNOI 10 lần Tiacutenh nghịch đảo modulo

C - Cu Chi Tunnel (1)

Taacutec giả Lecirc Đocircn Khuecirc

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Tham lam Ta sẽ tiến hagravenh gắn caacutec đỉnh vagraveo cacircy theo thứ tự từ 2 đến N Khi đoacute với đỉnh thứ i ta coacute thể gắn noacute vagraveo bất kigrave đỉnh nagraveo beacute hơn i magrave chưa đủ bậc Nếu tất cả caacutec đỉnh đều đatilde đủ bậc thigrave cacircu trả lời lagrave ldquoNOrdquo Cuối cugraveng nếu đatilde gắn xong đỉnh N magrave vẫn cograven đỉnh khocircng đủ bậc thigrave cũng in ra ldquoNOrdquo Viacute dụ 8

3 2 2 1 1 3 1 1

Đỉnh 2 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 1 1 0 0 0 0 0 0 Đỉnh 3 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 2 1 1 0 0 0 0 0 Đỉnh 4 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 3 1 1 1 0 0 0 0 Đỉnh 5 gắn với đỉnh 2 Mảng bậc hiện tại lagrave 3 2 1 1 1 0 0 0 Đỉnh 6 gắn với đỉnh 3 Mảng bậc hiện tại lagrave 3 2 2 1 1 1 0 0 Đỉnh 7 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 2 1 0 Đỉnh 8 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 3 1 1 Ta coacute thuật toaacuten độ phức tạp O(N^2) đủ để AC bagravei nagravey Nhưng ta coacute thể cải tiến thecircm bằng caacutech nhận xeacutet rằng ta chỉ cần quan tacircm đến tổng bậc cograven thiếu của caacutec đỉnh đatilde được gắn vagraveo cacircy magrave khocircng cần quan tacircm đến bậc cograven thiếu của từng đỉnh Do đoacute trong quaacute trigravenh duyệt ta chỉ cần lưu một biến cnt lagrave tổng bậc cograven thiếu hiện tại Độ phức tạp O(N)

D - Dropping Ball (4)

Taacutec giả Nguyễn Thagravenh Trung (RR)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned) Toacutem tắt đề bagravei Cho một bảng N x M với mỗi ocirc trong bảng coacute một trong 2 loại thanh lsquorsquo hoặc lsquorsquo Ta coacute Q truy vấn

- Đổi tường của một ocirc (ij) - Hỏi xem nếu thả một quả boacuteng vagraveo cột i thigrave quả boacuteng coacute thể xuống hagraveng cuối cugraveng rồi

ra khỏi bảng khocircng

Lời giải tracircu Để giải được toagraven bộ bagravei nagravey trước tiecircn ta phải nghĩ ra một lời giải tracircu nagraveo đoacute rồi tigravem caacutech cải tiến nếu coacute thể tuỳ vagraveo lời giải tracircu như nagraveo magrave cải tiến khaacutec nhau Coacute thể coi một ocirc (ij) bằng 2 nửa nửa trecircn vagrave nửa dưới Coi mỗi một nửa lagrave một đỉnh trecircn đồ thị Coacute thể dễ dagraveng nhận thấy mỗi một đỉnh nagravey chỉ coacute một đỉnh ra duy nhất tuỳ vagraveo loại thanh của caacutec ocirc xung quanh Nếu lagrave nửa dưới thigrave noacute chỉ coacute cạnh đi xuống dưới cograven nếu lagrave nửa trecircn thigrave noacute chỉ coacute cạnh đi sang một trong 2 ocirc becircn cạnh cugraveng hagraveng noacute Vậy với lời giải nagravey chỉ cần bfs lại toagraven bảng mỗi khi coacute truy vấn hỏi quả boacuteng đi đacircu

Lời giải tối ưu Lấy yacute tưởng bagravei httpcodeforcescomproblemsetproblem13E cugraveng với việc nhận ra N x M lt= 100 000 Migravenh đatilde coacute yacute tưởng chia bảng thagravenh những block caacutec hagraveng liecircn tiếp nhau mỗi block chứa xấp xỉ sqrt(N x M) ocirc Với mỗi block ta lưu lại được nếu thả quả boacuteng vagraveo cột j ở đầu block thigrave đến cuối block quả boacuteng sẽ ở cột nagraveo sử dụng lời giải tracircu ở trecircn Do vậy

- Truy vấn loại update ta thực hiện lại lời giải tracircu với tất cả caacutec ocirc thuộc block chứa ocirc (ij) cần update thực hiện lại việc bfs trecircn bảng Độ phức tạp thực hiện cocircng việc nagravey lagrave O(số ocirc của block) = O(sqrt(N x M)) Sau khi update với mỗi block ta coacute mảng nxt[j] = ocirc magrave quả boacuteng sẽ rơi xuống ở cuối block nếu quả boacuteng được thả ở cột j của block

- Truy vấn loại yecircu cầu trả lời Đi từ block 1 nhảy đến hagraveng đầu tiecircn của block 2 sử dụng thocircng tin trong block 1 tiếp tụchellip cho đến hết bảng Độ phức tạp (N x M (độ lớn mỗi block)) = O(sqrt(N x M))

Thế nhưng với trường hợp số hagraveng rất iacutet số cột rất to ta khocircng thể chia lagravem caacutec block sao cho mỗi block coacute iacutet hơn sqrt(N x M) phần tử được Do vậy với trường hợp N lt= sqrt(N x M) ta phải giải tracircu tức lagrave đi từ trecircn xuống dưới mỗi truy vấn mất đpt O(N) Thuật toaacuten nagravey bọn migravenh cảm thấy rất dễ code Với sự tinh tế của Nguyecircn team Unsigned đatilde hoagraven thagravenh việc code trong chỉ 15 phuacutet nộp phaacutet AC luocircn trong sự thăng hoa của team

E - Engaging with Loyal Customers (2) Thể loại Đồ thị Cặp gheacutep Lời giải Đacircy lagrave bagravei toaacuten cặp gheacutep coacute trọng số cực đại Để lagravem được bagravei nagravey caacutec bạn cần nắm vững Cặp gheacutep coacute trọng số trong saacutech thầy Lecirc Minh Hoagraveng (link) Cagravei đặt thuật toaacuten Hungary để giải Cặp gheacutep coacute trọng số code Một thuật toaacuten khaacutec cũng coacute thể dugraveng để giải cặp gheacutep coacute trọng số lagrave luồng mincost ( code) tuy nhiecircn khocircng thể chạy đủ nhanh vigrave đồ thị bagravei nagravey coacute 10^6 cạnh

F - Famous Pagoda (3)

Lời giải Nguyễn Thagravenh Trung - RR Thể loại Tối ưu hoaacute Quy hoạch động - Chia để trị Đặt cost(i j) lagrave chi phiacute để xacircy cầu thang từ điểm i đến j Đặt f(k i) = chi phiacute nhỏ nhất để k nhoacutem thợ xacircy tất cả cầu thang từ 1 đến i Ta coacute cocircng thức QHĐ

f(k i) = min( f(k-1 j) + cost(j+1 i) với j = 1i-1) Kết quả của bagravei toaacuten chiacutenh lagrave f(G N) Coacute 2 điểm mấu chốt của bagravei nagravey

Tiacutenh cost(i j) Tiacutenh nhanh bảng f(k i) Nếu tiacutenh trực tiếp theo cocircng thức trecircn ta mất độ phức tạp

O(GN^2) khocircng đủ để AC bagravei nagravey

1 Tiacutenh cost(i j) Với k = 1

Khi k = 1 điểm v chiacutenh lagrave median của datildey A(i)A(j) Do datildey A đatilde được sắp xếp tăng dần v = A[i + (j - i + 1) 2] Với mỗi (i j) ta coacute thể tiacutenh nhanh cost(i j) trong O(1) bằng mảng cộng dồn

Với k = 2

Đặt L = số phần tử của đoạn A(i)A(j) = j - i + 1 cost(i j) = sum( (a(s) - v)^2 )

= sum( a(s)^2 ) + Lv^2 + 2sum( a(s) )v Đặt B = 2sum( a(s) ) C = sum( a(s)^2 ) Ta tiacutenh được B vagrave C trong O(1) bằng mảng

cộng dồn cost(i j) = Lv^2 + Bv + C lagrave một hagravem bậc 2 của v Do đoacute điểm v để lagravem cost(i j) nhỏ

nhất chiacutenh lagrave v = -B L Tuy nhiecircn (-B L) coacute thể lagrave số thực cograven trong bagravei toaacuten nagravey v phải lagrave số nguyecircn necircn ta cần xeacutet 2 số nguyecircn v gần nhất với (-B L) bởi vigrave đồ thị hagravem số lồi

2 Tiacutenh f(k i) Để tiacutenh f(k i) ta cần dugraveng kĩ thuật QHĐ chia để trị Bạn coacute thể đọc lyacute thuyết ở VNOI wiki vagrave code ở đacircy Trong lời giải nagravey migravenh chỉ tập trung vagraveo việc chứng minh tiacutenh đuacuteng đắn của thuật toaacuten Nhắc lại ta coacute thể sử dụng được QHĐ chia để trị nếu

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 9: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

C - Cu Chi Tunnel (1)

Taacutec giả Lecirc Đocircn Khuecirc

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Tham lam Ta sẽ tiến hagravenh gắn caacutec đỉnh vagraveo cacircy theo thứ tự từ 2 đến N Khi đoacute với đỉnh thứ i ta coacute thể gắn noacute vagraveo bất kigrave đỉnh nagraveo beacute hơn i magrave chưa đủ bậc Nếu tất cả caacutec đỉnh đều đatilde đủ bậc thigrave cacircu trả lời lagrave ldquoNOrdquo Cuối cugraveng nếu đatilde gắn xong đỉnh N magrave vẫn cograven đỉnh khocircng đủ bậc thigrave cũng in ra ldquoNOrdquo Viacute dụ 8

3 2 2 1 1 3 1 1

Đỉnh 2 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 1 1 0 0 0 0 0 0 Đỉnh 3 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 2 1 1 0 0 0 0 0 Đỉnh 4 gắn với đỉnh 1 Mảng bậc hiện tại lagrave 3 1 1 1 0 0 0 0 Đỉnh 5 gắn với đỉnh 2 Mảng bậc hiện tại lagrave 3 2 1 1 1 0 0 0 Đỉnh 6 gắn với đỉnh 3 Mảng bậc hiện tại lagrave 3 2 2 1 1 1 0 0 Đỉnh 7 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 2 1 0 Đỉnh 8 gắn với đỉnh 6 Mảng bậc hiện tại lagrave 3 2 2 1 1 3 1 1 Ta coacute thuật toaacuten độ phức tạp O(N^2) đủ để AC bagravei nagravey Nhưng ta coacute thể cải tiến thecircm bằng caacutech nhận xeacutet rằng ta chỉ cần quan tacircm đến tổng bậc cograven thiếu của caacutec đỉnh đatilde được gắn vagraveo cacircy magrave khocircng cần quan tacircm đến bậc cograven thiếu của từng đỉnh Do đoacute trong quaacute trigravenh duyệt ta chỉ cần lưu một biến cnt lagrave tổng bậc cograven thiếu hiện tại Độ phức tạp O(N)

D - Dropping Ball (4)

Taacutec giả Nguyễn Thagravenh Trung (RR)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned) Toacutem tắt đề bagravei Cho một bảng N x M với mỗi ocirc trong bảng coacute một trong 2 loại thanh lsquorsquo hoặc lsquorsquo Ta coacute Q truy vấn

- Đổi tường của một ocirc (ij) - Hỏi xem nếu thả một quả boacuteng vagraveo cột i thigrave quả boacuteng coacute thể xuống hagraveng cuối cugraveng rồi

ra khỏi bảng khocircng

Lời giải tracircu Để giải được toagraven bộ bagravei nagravey trước tiecircn ta phải nghĩ ra một lời giải tracircu nagraveo đoacute rồi tigravem caacutech cải tiến nếu coacute thể tuỳ vagraveo lời giải tracircu như nagraveo magrave cải tiến khaacutec nhau Coacute thể coi một ocirc (ij) bằng 2 nửa nửa trecircn vagrave nửa dưới Coi mỗi một nửa lagrave một đỉnh trecircn đồ thị Coacute thể dễ dagraveng nhận thấy mỗi một đỉnh nagravey chỉ coacute một đỉnh ra duy nhất tuỳ vagraveo loại thanh của caacutec ocirc xung quanh Nếu lagrave nửa dưới thigrave noacute chỉ coacute cạnh đi xuống dưới cograven nếu lagrave nửa trecircn thigrave noacute chỉ coacute cạnh đi sang một trong 2 ocirc becircn cạnh cugraveng hagraveng noacute Vậy với lời giải nagravey chỉ cần bfs lại toagraven bảng mỗi khi coacute truy vấn hỏi quả boacuteng đi đacircu

Lời giải tối ưu Lấy yacute tưởng bagravei httpcodeforcescomproblemsetproblem13E cugraveng với việc nhận ra N x M lt= 100 000 Migravenh đatilde coacute yacute tưởng chia bảng thagravenh những block caacutec hagraveng liecircn tiếp nhau mỗi block chứa xấp xỉ sqrt(N x M) ocirc Với mỗi block ta lưu lại được nếu thả quả boacuteng vagraveo cột j ở đầu block thigrave đến cuối block quả boacuteng sẽ ở cột nagraveo sử dụng lời giải tracircu ở trecircn Do vậy

- Truy vấn loại update ta thực hiện lại lời giải tracircu với tất cả caacutec ocirc thuộc block chứa ocirc (ij) cần update thực hiện lại việc bfs trecircn bảng Độ phức tạp thực hiện cocircng việc nagravey lagrave O(số ocirc của block) = O(sqrt(N x M)) Sau khi update với mỗi block ta coacute mảng nxt[j] = ocirc magrave quả boacuteng sẽ rơi xuống ở cuối block nếu quả boacuteng được thả ở cột j của block

- Truy vấn loại yecircu cầu trả lời Đi từ block 1 nhảy đến hagraveng đầu tiecircn của block 2 sử dụng thocircng tin trong block 1 tiếp tụchellip cho đến hết bảng Độ phức tạp (N x M (độ lớn mỗi block)) = O(sqrt(N x M))

Thế nhưng với trường hợp số hagraveng rất iacutet số cột rất to ta khocircng thể chia lagravem caacutec block sao cho mỗi block coacute iacutet hơn sqrt(N x M) phần tử được Do vậy với trường hợp N lt= sqrt(N x M) ta phải giải tracircu tức lagrave đi từ trecircn xuống dưới mỗi truy vấn mất đpt O(N) Thuật toaacuten nagravey bọn migravenh cảm thấy rất dễ code Với sự tinh tế của Nguyecircn team Unsigned đatilde hoagraven thagravenh việc code trong chỉ 15 phuacutet nộp phaacutet AC luocircn trong sự thăng hoa của team

E - Engaging with Loyal Customers (2) Thể loại Đồ thị Cặp gheacutep Lời giải Đacircy lagrave bagravei toaacuten cặp gheacutep coacute trọng số cực đại Để lagravem được bagravei nagravey caacutec bạn cần nắm vững Cặp gheacutep coacute trọng số trong saacutech thầy Lecirc Minh Hoagraveng (link) Cagravei đặt thuật toaacuten Hungary để giải Cặp gheacutep coacute trọng số code Một thuật toaacuten khaacutec cũng coacute thể dugraveng để giải cặp gheacutep coacute trọng số lagrave luồng mincost ( code) tuy nhiecircn khocircng thể chạy đủ nhanh vigrave đồ thị bagravei nagravey coacute 10^6 cạnh

F - Famous Pagoda (3)

Lời giải Nguyễn Thagravenh Trung - RR Thể loại Tối ưu hoaacute Quy hoạch động - Chia để trị Đặt cost(i j) lagrave chi phiacute để xacircy cầu thang từ điểm i đến j Đặt f(k i) = chi phiacute nhỏ nhất để k nhoacutem thợ xacircy tất cả cầu thang từ 1 đến i Ta coacute cocircng thức QHĐ

f(k i) = min( f(k-1 j) + cost(j+1 i) với j = 1i-1) Kết quả của bagravei toaacuten chiacutenh lagrave f(G N) Coacute 2 điểm mấu chốt của bagravei nagravey

Tiacutenh cost(i j) Tiacutenh nhanh bảng f(k i) Nếu tiacutenh trực tiếp theo cocircng thức trecircn ta mất độ phức tạp

O(GN^2) khocircng đủ để AC bagravei nagravey

1 Tiacutenh cost(i j) Với k = 1

Khi k = 1 điểm v chiacutenh lagrave median của datildey A(i)A(j) Do datildey A đatilde được sắp xếp tăng dần v = A[i + (j - i + 1) 2] Với mỗi (i j) ta coacute thể tiacutenh nhanh cost(i j) trong O(1) bằng mảng cộng dồn

Với k = 2

Đặt L = số phần tử của đoạn A(i)A(j) = j - i + 1 cost(i j) = sum( (a(s) - v)^2 )

= sum( a(s)^2 ) + Lv^2 + 2sum( a(s) )v Đặt B = 2sum( a(s) ) C = sum( a(s)^2 ) Ta tiacutenh được B vagrave C trong O(1) bằng mảng

cộng dồn cost(i j) = Lv^2 + Bv + C lagrave một hagravem bậc 2 của v Do đoacute điểm v để lagravem cost(i j) nhỏ

nhất chiacutenh lagrave v = -B L Tuy nhiecircn (-B L) coacute thể lagrave số thực cograven trong bagravei toaacuten nagravey v phải lagrave số nguyecircn necircn ta cần xeacutet 2 số nguyecircn v gần nhất với (-B L) bởi vigrave đồ thị hagravem số lồi

2 Tiacutenh f(k i) Để tiacutenh f(k i) ta cần dugraveng kĩ thuật QHĐ chia để trị Bạn coacute thể đọc lyacute thuyết ở VNOI wiki vagrave code ở đacircy Trong lời giải nagravey migravenh chỉ tập trung vagraveo việc chứng minh tiacutenh đuacuteng đắn của thuật toaacuten Nhắc lại ta coacute thể sử dụng được QHĐ chia để trị nếu

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 10: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

D - Dropping Ball (4)

Taacutec giả Nguyễn Thagravenh Trung (RR)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned) Toacutem tắt đề bagravei Cho một bảng N x M với mỗi ocirc trong bảng coacute một trong 2 loại thanh lsquorsquo hoặc lsquorsquo Ta coacute Q truy vấn

- Đổi tường của một ocirc (ij) - Hỏi xem nếu thả một quả boacuteng vagraveo cột i thigrave quả boacuteng coacute thể xuống hagraveng cuối cugraveng rồi

ra khỏi bảng khocircng

Lời giải tracircu Để giải được toagraven bộ bagravei nagravey trước tiecircn ta phải nghĩ ra một lời giải tracircu nagraveo đoacute rồi tigravem caacutech cải tiến nếu coacute thể tuỳ vagraveo lời giải tracircu như nagraveo magrave cải tiến khaacutec nhau Coacute thể coi một ocirc (ij) bằng 2 nửa nửa trecircn vagrave nửa dưới Coi mỗi một nửa lagrave một đỉnh trecircn đồ thị Coacute thể dễ dagraveng nhận thấy mỗi một đỉnh nagravey chỉ coacute một đỉnh ra duy nhất tuỳ vagraveo loại thanh của caacutec ocirc xung quanh Nếu lagrave nửa dưới thigrave noacute chỉ coacute cạnh đi xuống dưới cograven nếu lagrave nửa trecircn thigrave noacute chỉ coacute cạnh đi sang một trong 2 ocirc becircn cạnh cugraveng hagraveng noacute Vậy với lời giải nagravey chỉ cần bfs lại toagraven bảng mỗi khi coacute truy vấn hỏi quả boacuteng đi đacircu

Lời giải tối ưu Lấy yacute tưởng bagravei httpcodeforcescomproblemsetproblem13E cugraveng với việc nhận ra N x M lt= 100 000 Migravenh đatilde coacute yacute tưởng chia bảng thagravenh những block caacutec hagraveng liecircn tiếp nhau mỗi block chứa xấp xỉ sqrt(N x M) ocirc Với mỗi block ta lưu lại được nếu thả quả boacuteng vagraveo cột j ở đầu block thigrave đến cuối block quả boacuteng sẽ ở cột nagraveo sử dụng lời giải tracircu ở trecircn Do vậy

- Truy vấn loại update ta thực hiện lại lời giải tracircu với tất cả caacutec ocirc thuộc block chứa ocirc (ij) cần update thực hiện lại việc bfs trecircn bảng Độ phức tạp thực hiện cocircng việc nagravey lagrave O(số ocirc của block) = O(sqrt(N x M)) Sau khi update với mỗi block ta coacute mảng nxt[j] = ocirc magrave quả boacuteng sẽ rơi xuống ở cuối block nếu quả boacuteng được thả ở cột j của block

- Truy vấn loại yecircu cầu trả lời Đi từ block 1 nhảy đến hagraveng đầu tiecircn của block 2 sử dụng thocircng tin trong block 1 tiếp tụchellip cho đến hết bảng Độ phức tạp (N x M (độ lớn mỗi block)) = O(sqrt(N x M))

Thế nhưng với trường hợp số hagraveng rất iacutet số cột rất to ta khocircng thể chia lagravem caacutec block sao cho mỗi block coacute iacutet hơn sqrt(N x M) phần tử được Do vậy với trường hợp N lt= sqrt(N x M) ta phải giải tracircu tức lagrave đi từ trecircn xuống dưới mỗi truy vấn mất đpt O(N) Thuật toaacuten nagravey bọn migravenh cảm thấy rất dễ code Với sự tinh tế của Nguyecircn team Unsigned đatilde hoagraven thagravenh việc code trong chỉ 15 phuacutet nộp phaacutet AC luocircn trong sự thăng hoa của team

E - Engaging with Loyal Customers (2) Thể loại Đồ thị Cặp gheacutep Lời giải Đacircy lagrave bagravei toaacuten cặp gheacutep coacute trọng số cực đại Để lagravem được bagravei nagravey caacutec bạn cần nắm vững Cặp gheacutep coacute trọng số trong saacutech thầy Lecirc Minh Hoagraveng (link) Cagravei đặt thuật toaacuten Hungary để giải Cặp gheacutep coacute trọng số code Một thuật toaacuten khaacutec cũng coacute thể dugraveng để giải cặp gheacutep coacute trọng số lagrave luồng mincost ( code) tuy nhiecircn khocircng thể chạy đủ nhanh vigrave đồ thị bagravei nagravey coacute 10^6 cạnh

F - Famous Pagoda (3)

Lời giải Nguyễn Thagravenh Trung - RR Thể loại Tối ưu hoaacute Quy hoạch động - Chia để trị Đặt cost(i j) lagrave chi phiacute để xacircy cầu thang từ điểm i đến j Đặt f(k i) = chi phiacute nhỏ nhất để k nhoacutem thợ xacircy tất cả cầu thang từ 1 đến i Ta coacute cocircng thức QHĐ

f(k i) = min( f(k-1 j) + cost(j+1 i) với j = 1i-1) Kết quả của bagravei toaacuten chiacutenh lagrave f(G N) Coacute 2 điểm mấu chốt của bagravei nagravey

Tiacutenh cost(i j) Tiacutenh nhanh bảng f(k i) Nếu tiacutenh trực tiếp theo cocircng thức trecircn ta mất độ phức tạp

O(GN^2) khocircng đủ để AC bagravei nagravey

1 Tiacutenh cost(i j) Với k = 1

Khi k = 1 điểm v chiacutenh lagrave median của datildey A(i)A(j) Do datildey A đatilde được sắp xếp tăng dần v = A[i + (j - i + 1) 2] Với mỗi (i j) ta coacute thể tiacutenh nhanh cost(i j) trong O(1) bằng mảng cộng dồn

Với k = 2

Đặt L = số phần tử của đoạn A(i)A(j) = j - i + 1 cost(i j) = sum( (a(s) - v)^2 )

= sum( a(s)^2 ) + Lv^2 + 2sum( a(s) )v Đặt B = 2sum( a(s) ) C = sum( a(s)^2 ) Ta tiacutenh được B vagrave C trong O(1) bằng mảng

cộng dồn cost(i j) = Lv^2 + Bv + C lagrave một hagravem bậc 2 của v Do đoacute điểm v để lagravem cost(i j) nhỏ

nhất chiacutenh lagrave v = -B L Tuy nhiecircn (-B L) coacute thể lagrave số thực cograven trong bagravei toaacuten nagravey v phải lagrave số nguyecircn necircn ta cần xeacutet 2 số nguyecircn v gần nhất với (-B L) bởi vigrave đồ thị hagravem số lồi

2 Tiacutenh f(k i) Để tiacutenh f(k i) ta cần dugraveng kĩ thuật QHĐ chia để trị Bạn coacute thể đọc lyacute thuyết ở VNOI wiki vagrave code ở đacircy Trong lời giải nagravey migravenh chỉ tập trung vagraveo việc chứng minh tiacutenh đuacuteng đắn của thuật toaacuten Nhắc lại ta coacute thể sử dụng được QHĐ chia để trị nếu

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 11: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

E - Engaging with Loyal Customers (2) Thể loại Đồ thị Cặp gheacutep Lời giải Đacircy lagrave bagravei toaacuten cặp gheacutep coacute trọng số cực đại Để lagravem được bagravei nagravey caacutec bạn cần nắm vững Cặp gheacutep coacute trọng số trong saacutech thầy Lecirc Minh Hoagraveng (link) Cagravei đặt thuật toaacuten Hungary để giải Cặp gheacutep coacute trọng số code Một thuật toaacuten khaacutec cũng coacute thể dugraveng để giải cặp gheacutep coacute trọng số lagrave luồng mincost ( code) tuy nhiecircn khocircng thể chạy đủ nhanh vigrave đồ thị bagravei nagravey coacute 10^6 cạnh

F - Famous Pagoda (3)

Lời giải Nguyễn Thagravenh Trung - RR Thể loại Tối ưu hoaacute Quy hoạch động - Chia để trị Đặt cost(i j) lagrave chi phiacute để xacircy cầu thang từ điểm i đến j Đặt f(k i) = chi phiacute nhỏ nhất để k nhoacutem thợ xacircy tất cả cầu thang từ 1 đến i Ta coacute cocircng thức QHĐ

f(k i) = min( f(k-1 j) + cost(j+1 i) với j = 1i-1) Kết quả của bagravei toaacuten chiacutenh lagrave f(G N) Coacute 2 điểm mấu chốt của bagravei nagravey

Tiacutenh cost(i j) Tiacutenh nhanh bảng f(k i) Nếu tiacutenh trực tiếp theo cocircng thức trecircn ta mất độ phức tạp

O(GN^2) khocircng đủ để AC bagravei nagravey

1 Tiacutenh cost(i j) Với k = 1

Khi k = 1 điểm v chiacutenh lagrave median của datildey A(i)A(j) Do datildey A đatilde được sắp xếp tăng dần v = A[i + (j - i + 1) 2] Với mỗi (i j) ta coacute thể tiacutenh nhanh cost(i j) trong O(1) bằng mảng cộng dồn

Với k = 2

Đặt L = số phần tử của đoạn A(i)A(j) = j - i + 1 cost(i j) = sum( (a(s) - v)^2 )

= sum( a(s)^2 ) + Lv^2 + 2sum( a(s) )v Đặt B = 2sum( a(s) ) C = sum( a(s)^2 ) Ta tiacutenh được B vagrave C trong O(1) bằng mảng

cộng dồn cost(i j) = Lv^2 + Bv + C lagrave một hagravem bậc 2 của v Do đoacute điểm v để lagravem cost(i j) nhỏ

nhất chiacutenh lagrave v = -B L Tuy nhiecircn (-B L) coacute thể lagrave số thực cograven trong bagravei toaacuten nagravey v phải lagrave số nguyecircn necircn ta cần xeacutet 2 số nguyecircn v gần nhất với (-B L) bởi vigrave đồ thị hagravem số lồi

2 Tiacutenh f(k i) Để tiacutenh f(k i) ta cần dugraveng kĩ thuật QHĐ chia để trị Bạn coacute thể đọc lyacute thuyết ở VNOI wiki vagrave code ở đacircy Trong lời giải nagravey migravenh chỉ tập trung vagraveo việc chứng minh tiacutenh đuacuteng đắn của thuật toaacuten Nhắc lại ta coacute thể sử dụng được QHĐ chia để trị nếu

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 12: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

F - Famous Pagoda (3)

Lời giải Nguyễn Thagravenh Trung - RR Thể loại Tối ưu hoaacute Quy hoạch động - Chia để trị Đặt cost(i j) lagrave chi phiacute để xacircy cầu thang từ điểm i đến j Đặt f(k i) = chi phiacute nhỏ nhất để k nhoacutem thợ xacircy tất cả cầu thang từ 1 đến i Ta coacute cocircng thức QHĐ

f(k i) = min( f(k-1 j) + cost(j+1 i) với j = 1i-1) Kết quả của bagravei toaacuten chiacutenh lagrave f(G N) Coacute 2 điểm mấu chốt của bagravei nagravey

Tiacutenh cost(i j) Tiacutenh nhanh bảng f(k i) Nếu tiacutenh trực tiếp theo cocircng thức trecircn ta mất độ phức tạp

O(GN^2) khocircng đủ để AC bagravei nagravey

1 Tiacutenh cost(i j) Với k = 1

Khi k = 1 điểm v chiacutenh lagrave median của datildey A(i)A(j) Do datildey A đatilde được sắp xếp tăng dần v = A[i + (j - i + 1) 2] Với mỗi (i j) ta coacute thể tiacutenh nhanh cost(i j) trong O(1) bằng mảng cộng dồn

Với k = 2

Đặt L = số phần tử của đoạn A(i)A(j) = j - i + 1 cost(i j) = sum( (a(s) - v)^2 )

= sum( a(s)^2 ) + Lv^2 + 2sum( a(s) )v Đặt B = 2sum( a(s) ) C = sum( a(s)^2 ) Ta tiacutenh được B vagrave C trong O(1) bằng mảng

cộng dồn cost(i j) = Lv^2 + Bv + C lagrave một hagravem bậc 2 của v Do đoacute điểm v để lagravem cost(i j) nhỏ

nhất chiacutenh lagrave v = -B L Tuy nhiecircn (-B L) coacute thể lagrave số thực cograven trong bagravei toaacuten nagravey v phải lagrave số nguyecircn necircn ta cần xeacutet 2 số nguyecircn v gần nhất với (-B L) bởi vigrave đồ thị hagravem số lồi

2 Tiacutenh f(k i) Để tiacutenh f(k i) ta cần dugraveng kĩ thuật QHĐ chia để trị Bạn coacute thể đọc lyacute thuyết ở VNOI wiki vagrave code ở đacircy Trong lời giải nagravey migravenh chỉ tập trung vagraveo việc chứng minh tiacutenh đuacuteng đắn của thuật toaacuten Nhắc lại ta coacute thể sử dụng được QHĐ chia để trị nếu

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 13: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

cost(a d) + cost(b c) gt= cost(a c) + cost(b d) với mọi a lt b lt c lt d Đặt

f(i j v) = (sum (|a(s) - v|^k) với s = ij) v_opt(a b) = v để f(a b v) đạt giaacute trị nhỏ nhất cost(a b) = f(a b v_opt(a b)) lt= f(a b v) với mọi v

Khocircng lagravem mất tiacutenh tổng quaacutet giả sử v_opt(b c) lt= v_opt(a d) Ngoagravei ra ta cũng biết rằng v_opt(b c) nằm trong khoảng [b c]

Ta coacute cost(a d) = f(a d v_opt(a d)) = f(a b-1 v_opt(a d)) + f(b d v_opt(a d)) gt= f(a b-1 v_opt(a d)) + cost(b d) Mặt khaacutec do tất cả đoạn [a b-1] ở becircn traacutei v_opt(b c) vagrave v_opt(b c) lt v_opt(a d) necircn f(a b-1 v_opt(a d)) + cost(b c) gt= f(a b-1 v_opt(b c)) + cost(b c) = f(a b-1 v_opt(b c)) + f(b c v_opt(b c)) = f(a c v_opt(b c)) gt= cost(a c) Kết hợp 2 bất đẳng thức trecircn cost(a d) + cost(b c) gt= f(a b-1 v_opt(a d)) + cost(b d) + cost(b c) = f(a b-1 v_opt(a d)) + cost(b c) + cost(b d) gt= cost(a c) + cost(b d) Chứng minh hoagraven tất Kết luận ta coacute thể dugraveng QHĐ chia để trị để giải bagravei toaacuten với độ phức tạp O(GNlog(G))

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 14: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

G - Game of Divisibility (3)

Taacutec giả thầy Hiếu (Hưng Yecircn) + Lăng Trung Hiếu

Lời giải Đại Ca Đi Học Giả sử người đi trước lagrave A người đi sau lagrave B Gọi s[i] lagrave số lượng số chia k dư i (0leiltk) X lagrave số lượng giaacute trị i coacute s_i lẻ

X=0 Trận đấu hogravea Cả A vagrave B đều coacute chiến lược để migravenh khocircng thể thua Do đoacute trận đấu hogravea

X = 1 Nếu người lấy số dư lẻ ra (t) thắng thigrave A luocircn lagrave người lấy được Nếu người lấy phần dư lẻ ra thua thigrave B luocircn bắt A phải lấy phần đoacute Do đoacute A luocircn lagrave người lấy phần số dư lẻ ra Số dư A nhận được lagrave (t+(sum-t)2) số dư B nhận được lagrave (sum-t)2

X=2 số dư lẻ 2 lagrave pqA được quyền quyết định lấy số dư p hoặc q lẻ Sau đoacute trở về trạng thaacutei X=1 như trecircn B sẽ bắt buộc lấy số dư cograven lại Trong trường hợp nagravey A chọn 1 trong 2 A sẽ chọn số dư coacute khả năng thắng Ở trường hợp nagravey nếu cả 2 đều khocircng coacute khả năng thắng A sẽ chọn số dư để hogravea (Chắc chắn khocircng thua)

X=3 Sau khi chọn 1 số dư lẻ sẽ về trạng thaacutei X=2 Người nhận trạng thaacutei nagravey khocircng bao giờ thua Necircn người ở trạng thaacutei X=3 cũng coacute quyền tự quyết chọn để người ở trạng thaacutei X=2 khocircng thể thắng Do đoacute X=3 lagrave trạng thaacutei 2 người khocircng thể thua HOgraveA

Tương tự caacutec trường hợp Xgt2 tất cả sẽ đều hogravea

Ghi chuacute Đacircy lagrave bagravei toaacuten 3 cực khoacute chứ khocircng dễ như sau khi nhigraven lướt qua lời giải trecircn chỉ dagravenh cho những bạn đatilde cực kỳ xuất sắc về dạng nagravey muốn hiểu rotilde thecircm bạn cần đọc đoạn giải thiacutech lưu yacute lagrave coacute thể đọc xong giải thiacutech cagraveng khoacute hiểu thecircm Bagravei B với bagravei J coacute chứa nhiều trap nhưng bản thacircn bagravei G lại lagrave một caacutei trap cực lớn caacutec dữ kiện như n lt= 1000 k lt= 32 chỉ mang tiacutenh chất hoa mỹ khocircng liecircn quan gigrave đến lời giải đặc biệt lagrave a[i] lt= 2^31 lagravem tỉ lệ WA tăng lecircn đaacuteng kể Chiacutenh vigrave thế để giải được bagravei nagravey caacutec bạn cần phải tư duy thuần tuyacute mạnh mẽ chứ khocircng được baacutem theo lối mograven suy nghĩ như kiểu coacute thể nhigraven được cocircng thức hay dugraveng giới hạn để đoaacuten thuật toaacuten

Giải thiacutech X = 0 cả A vagrave B đều coacute thể coacute chiến lược để bằng điểm đối phương Đối với B chỉ cần chọn số coacute số dư giống A vừa chọn Đối với A coacute thể start bằng số bất kỳ xong chơi giống hệt B nếu khocircng tồn tại số coacute số dư bằng số B vừa chọn thigrave lại chọn số bất kỳ đến hết Ta thấy sau mỗi lượt A chơi thigrave đều chỉ coacute tối đa 1 tập số dư coacute lẻ số Với X = 1 nếu số dư lẻ ra coacute lợi cho A A sẽ chọn số đấy rồi chơi chiến thuật chọn giống B Cograven ngược lại B sẽ chọn chiến lược chọn giống A eacutep A phải chọn hơn B 1 lần chiacutenh lagrave số dư lẻ ra đoacute Caacutec bạn coacute thể dugraveng suy nghĩ như vậy để aacutep dụng với X gt= 2 vagrave những bagravei toaacuten tương tự liecircn quan đến trograve chơi giữa hai người vagrave số dư

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 15: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

H - Height Preservation (2)

Lời giải Nguyễn Diệp Xuacircn Quang (team HCMUS - Illuminate) Thể loại Đồ thị Topo sort Trước hết ta sẽ gộp caacutec ocirc coacute giaacute trị giống nhau ở cugraveng một dograveng hoặc cugraveng một cột vagraveo một thagravenh phần liecircn thocircng (ta gọi lagrave siecircu đỉnh) Việc tigravem caacutec cặp ocirc để gộp coacute thể thực hiện bằng caacutech duyệt từng dograveng sắp xếp caacutec ocirc trecircn từng dograveng theo thứ tự tăng dần vagrave thecircm cạnh giữa hai ocirc trecircn cột j vagrave cột j+1 của dograveng hiện tại nếu số trecircn hai ocirc nagravey bằng nhau (Với từng cột cũng lagravem tương tự) Việc gộp ocirc coacute thể lagravem bằng DSU hoặc DFS Sau đoacute ta duyệt từng dograveng sắp xếp caacutec ocirc trecircn dograveng theo thứ tự tăng dần rồi thecircm cạnh một chiều nối từ siecircu đỉnh chứa ocirc trecircn cột j đến siecircu đỉnh chứa ocirc trecircn cột j+1 của dograveng hiện tại nếu số trecircn cột j nhỏ hơn số trecircn cocirct j+1 Ta lagravem tương tự như vậy với từng cột Cuối cugraveng ta sẽ được một DAG trecircn caacutec siecircu đỉnh Đaacutep số cần tigravem chiacutenh lagrave số đỉnh trecircn đường đi dagravei nhất của DAG nagravey Bagravei toaacuten tigravem độ dagravei đường đi dagravei nhất trecircn DAG lagrave một bagravei toaacuten quy hoạch động kinh điển coacute thể giải được trong O(N+M) (với N lagrave số đỉnh trong DAG M lagrave số cạnh trong DAG) Độ phức tạp O(NMlog(N+M))

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 16: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

I - ICPC Awards (0)

Taacutec giả Lecirc Đocircn Khuecirc Bagravei nagravey được ra với mục điacutech tất cả caacutec đội tham gia cuộc thi đều giải được iacutet nhất 1 bagravei Đaacuteng tiếc lagrave vẫn cograven một đội khocircng giải được Bagravei toaacuten nagravey chỉ đogravei hỏi biết sử dụng C++ STL

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 17: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

J - Joining Networks (3)

Taacutec giả Lăng Trung Hiếu

Lời giải Phạm Cao Nguyecircn (team VNU - unsigned) Thể loại Quy hoạch động bao lồi

Toacutem tắt đề bagravei Cho 2 cacircy lt= 50000 đỉnh tigravem caacutech nối 1 cạnh giữa 2 cacircy để tổng bigravenh phương khoảng caacutech giữa mọi cặp đỉnh lagrave nhỏ nhất

Lời giải Đacircy lagrave một bagravei thuộc loại cổ điển viết kĩ cocircng thức rồi tiacutenh từng phần một Kiến thức cần biết Quy hoạch động trecircn cacircy Bao lồi đường thẳng Kiecircn trigrave phaacute ngoặc

Phacircn tiacutech cocircng thức Ta định nghĩa f(T a b) lagrave khoảng caacutech giữa 2 nuacutet a vagrave b trecircn cacircy T Xeacutet 2 cacircy A (N nuacutet) vagrave B (M nuacutet) khi nối đỉnh u của cacircy A với đỉnh v của cacircy B ta coacute khoảng caacutech giữa mọi cặp đỉnh như sau

(A i j) (B i j) (f (A u i) f (B v j) 1) C = sumN

i = 1sumi minus 1

j = 1f 2 + sum

M

i = 1sumi minus 1

j = 1f 2 + sum

N

i = 1sumM

j = 1 + + 2

2 tổng đầu tiecircn khaacute dễ hiểu chuacuteng chỉ lagrave tổng bigravenh phương giữa mọi cặp đỉnh trong cacircy Noacute khocircng quaacute khoacute tiacutenh (qhđ trecircn cacircy cơ bản thocirci) vagrave khocircng đổi với mọi caacutech chọn u v necircn ta tạm thời bỏ ra khỏi phương trigravenh Phần cograven lại ta phacircn tiacutech sẽ ra

(f (A u i) f (B v j) 1) sumN

i = 1sumM

j = 1 + + 2

= +(A u i) M (B v j) N ( (A u i) M (B v j) NsumN

i = 1f 2 + sum

M

j = 1f 2 + N M + 2 sum

N

i = 1f + sum

M

j = 1f

(A u i) f (B v j))sumN

i = 1f sum

M

j = 1

Gọi S(T u) lagrave tổng khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Sq(T u) lagrave tổng bigravenh phương khoảng caacutech từ đỉnh u đến tất cả caacutec nuacutet cograven lại của cacircy T Ta coacute thể viết lại cocircng thức thagravenh

q(A u) N Sq(B v) 2(M S(A u) N S(B v) S(A u) S(B v))M S + + + + Gom lại caacutec phần độc lập theo u v cho dễ nhigraven ta coacute

q(A u) 2M S(A u) N Sq(B v) 2N S(B v) 2S(A u) S(B v)M S + + + +

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 18: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

Như vậy chỉ coacute phần 2S(A u)S(B v) lagrave phụ thuộc vagraveo cả 2 đại lượng u vagrave v Tuy nhiecircn khocircng khoacute để nhigraven ra đacircy lagrave đại lượng tuyến tiacutenh necircn khi ta coi S(A u) lagrave hằng số S(B v) lagrave biến cocircng thức trở thagravenh cocircng thức đường thẳng Đối với caacutec bạn đatilde quen thuộc với việc sử dụng thủ thuật bao lồi trong quy hoạch động đacircy lagrave một dạng tương tự Ta sẽ dựng bao lồi caacutec đường thẳng của u sau đoacute truy vấn v trecircn bao lồi đoacute Toacutem lại caacutec phần cần tiacutenh bao gồm

- S(A u) vagrave S(B v) cho mọi u v - Sq(A u) vagrave Sq(B v) cho mọi u v

Tiacutenh S(A u) Trước tiecircn vigrave 2 cacircy lagrave độc lập necircn trong phần nagravey ta sẽ gọi S(A u) lagrave S(u) cho ngắn gọn Đacircy lagrave bagravei toaacuten qhđ cơ bản đatilde xuất hiện trong 1 số bagravei tập trecircn VNOI (httpvnoiinfoproblemsshowNTTREE) Caacutech lagravem như sau

- Đầu tiecircn tiacutenh size[v] lagrave số đỉnh trong cacircy con gốc v - Thực hiện qhđ trecircn cacircy để tiacutenh down[u] tổng khoảng caacutech giữa u vagrave caacutec đỉnh trong cacircy

con gốc u Cocircng thức lagrave Nocircm na lagrave vigrave tất cảown[u] hild[v] size[v]d = sum

v ε child[u]c +

khoảng caacutech từ u đến caacutec caacutec đỉnh thuộc cacircy con gốc v đều hơn 1 so với khoảng caacutech từ v necircn tổng của chuacuteng sẽ cộng thecircm một lượng lagrave số đỉnh trong cacircy con gốc v Ta coacute thể tiacutenh caacutec giaacute trị size[v] bằng 1 lần dfs

- Giờ ta sẽ tiacutenh up[u] tổng khoảng caacutech từ u đến caacutec đỉnh khocircng nằm trong cacircy con gốc u Khocircng khoacute để nhigraven thấy up[u] gồm 2 phần

- Caacutec đỉnh khocircng thuộc cacircy con gốc parent(u) Phần nagravey được tiacutenh bằng up[parent(u)] + (N -size[parent(u)])

- Caacutec đỉnh thuộc cacircy con gốc parent(u) nhưng khocircng thuộc cacircy con gốc u Phần nagravey được tiacutenh bằng down[parent(u)] + size[parent(u)] - (down[u] - size[u])

- Tổng lại ta coacute up[u] = up[parent(u)] + down[parent(u)] - down[u] + (N - size[u]) - Phần nagravey cũng coacute thể được tiacutenh bằng một pheacutep dfs Mặc định nếu 1 lagrave gốc ta

coacute up[1] = 0 - Hiển nhiecircn S[u] = down[u] + up[u] theo định nghĩa Ta tiacutenh thagravenh cocircng S[u] trong O(n)

Tiacutenh Sq(A u) Tương tự phần trecircn ta gọi Sq(A u) lagrave Sq(u) cho đơn giản Việc tiacutenh Sq(A u) yecircu cầu coacute caacutec giaacute trị size[u] down[u] up[u] đatilde tiacutenh ở trecircn Ta thực hiện như sau

- Đầu tiecircn cũng như bagravei trecircn ta tiacutenh downsq[u] lagrave tổng bigravenh phương khoảng caacutech từ u đến caacutec đỉnh thuộc cacircy con gốc u Vậy với mỗi v lagrave con của u downsq[u] tăng thecircm bao nhiecircu Ta coacute downsq[v] = tổng caacutec d(v i)^2 với i thuộc cacircy con gốc v Vậy downsq[u] += tổng (d(v i) + 1)^2 hay downsq[u] += tổng d(v i)^2 + 2 tổng d(v i) + size[v] = downsq[v] + 2 down[v] + size[v] Việc tiacutenh downsq[u] vẫn coacute thể tiacutenh bằng 1 lần dfs

- Tiếp tục tiacutenh upsq[u] Với caacutech phacircn tiacutech tương tự ta sẽ coacute - Phần khocircng thuộc cacircy con gốc parent(u)

upsq[parent(u)] + 2up[parent(u)] + (N - size[parent(u)])

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 19: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

- Phần thuộc cacircy con gốc parent(u) downsq[parent(u)] - (downsq[u] + 2 down[u] + size[u]) + 2 (down[parent(u)] - (down[u] + size[u])) + (size[parent(u)] - size[u])

- upsq[u] sẽ lagrave tổng của 2 giaacute trị trecircn - Sq[u] = downsq[u] + upsq[u]

Như vậy việc tiacutenh Sq(A u) cũng coacute thể thực hiện trong O(N)

Dựng bao lồi Cograven lại chỉ lagrave việc dựng bao lồi vagrave tiacutenh giaacute trị nhỏ nhất Theo như cocircng thức trecircn đỉnh u sẽ được biểu diễn dưới dạng đường thẳng coacute a = 2S(A u) b =

q(A u) 2M S(A u)M S + Khi truy vấn đỉnh v ta truy vấn tọa độ x = S(B v) vagrave cộng thecircm Sq(B v) 2N S(B v)N + để ra giaacute trị tối ưu khi chọn đỉnh v Đaacutep số sẽ lagrave min của caacutec giaacute trị đối với caacutec lựa chọn v Để yacute ta hoagraven toagraven coacute thể thecircm tất cả đường thẳng vagraveo trước khi truy vấn necircn ta necircn sort lại caacutec đỉnh u theo slope (a = 2S(A u)) giảm dần để dễ dagraveng dựng bao lồi Ta cũng khocircng cần thực hiện truy vấn theo đuacuteng thứ tự sort lại caacutec truy vấn theo tọa độ tăng dần để khocircng cần chặt nhị phacircn khi truy vấn trecircn bao lồi giảm thời gian cagravei đặt Việc dựng bao lồi coacute thể tham khảo trecircn httpvnoiinfowikitranslatewcipegConvex-Hull-Trick Độ phức tạp của cả bagravei toaacuten lagrave O(N log N)

Lưu yacute - Khi so saacutenh 2 đường thẳng trecircn bao lồi khocircng thể dugraveng pheacutep nhacircn cheacuteo vigrave sẽ bị tragraven số

Sử dụng chia bằng long double đủ qua - Đaacutep số lớn hơn 1e18 hatildey sử dụng hằng số vocirc tận lớn hơn - Coacute khaacute nhiều đội để N M lagrave kiểu int necircn bị tragraven số khi tiacutenh tiacutech N M

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 20: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

K - K-rotating (3)

Lời giải Lecirc Quang Tuấn (team VNU - unsigned)

Toacutem tắt đề bagravei Cho N cocirc giaacuteo vagrave N lớp mỗi cocirc giaacuteo dạy ở một lớp Ban đầu cocirc giaacuteo thứ i dạy cho lớp thứ j Vagrave mỗi tuần coacute thể coacute một số sự thay đổi ở vị triacute của caacutec cocirc giaacuteo (lưu yacute lagrave số sự thay đổi mỗi tuần lt= 10) Coacute 2 loại truy vấn

- Thecircm một sự thay đổi về lớp của caacutec cocirc giaacuteo - Hỏi xem ở tuần thứ x sau khi đatilde thực hiện xong việc thay đổi ở tuần thứ x thigrave cocirc giaacuteo

thứ y dạy ở lớp nagraveo

Lời giải Với bagravei nagravey migravenh nghĩ đến ngay phải chia căn lại phải nhảy nhảy như bagravei D Thế nhưng chia căn như nagraveo tiacutenh như nagraveo thigrave mới chia căn được mới lagrave vấn đề Để nghĩ ra một lời giải tracircu thigrave khocircng khoacute thế nhưng nghĩ ra một lời giải tracircu để chia căn được thigrave lại rất khoacute Ở bagravei nagravey lời giải tracircu như sau

- Tiacutenh hagravem f[x][y] được trả về ở ngagravey x cocirc giaacuteo thứ y đang dạy lớp của cocirc giaacuteo nagraveo trong tuần x - 1 Tức lagrave f[x][y] trả về k coacute nghĩa lagrave lớp của cocirc giaacuteo k ở tuần x - 1sẽ được chuyển thagravenh cocirc lớp của cocirc giaacuteo y ở tuần x

- Tiacutenh hagravem f[x][y] như nagraveo Ban đầu f[x][y] = y Nếu ở tuần x ta phải swap lớp của 2 cocirc p vagrave cocirc q thigrave ta cũng swap luocircn f[x][p] vagrave f[x][q]

- Khi coacute hagravem f rồi để truy vấn ta chỉ cần đi từ tuần x về tuần 1y = f[x][y] Thigrave đến cuối cugraveng y sẽ lagrave lớp cần tigravem

Theo migravenh thấy thigrave những lời giải tracircu đi từ tuần 1 đến tuần x đều khocircng khả thi cho việc chia căn chỉ coacute caacutech đi từ tuần x về tuần 1 lagrave khả thi Giờ phải chia căn như nagraveo Tất nhiecircn lagrave chia lagravem sqrt(M) block mỗi block gồm xấp xỉ sqrt(M) tuần Với mỗi block ta lưu lại f[y] lagrave ở tuần cuối của block cocirc giaacuteo y sẽ dạy lớp của cocirc giaacuteo nagraveo ở đầu block

- Update Với mỗi truy vấn update tiacutenh lại toagraven bộ hagravem f[] của block Độ phức tạp O(sqrt(M) 10) Do tối ta chỉ coacute 10 pheacutep swap mỗi tuần

- Truy vấn Đi tracircu từ tuần x về cuối của một block rồi sau đoacute dugraveng hagravem f[] của mỗi block để nhảy về block trước như thuật tracircu chỉ ở trecircn Đpt (sqrt(M) 10)

Bộ nhớ O(sqrt(M) N) vigrave mỗi block ta phải lưu lại mảng f[] gồm N phần tử Để tối ưu caacutec bạn necircn chia lớn hơn sqrt(M) block vagrave mỗi block coacute độ dagravei nhỏ hơn sqrt(M)

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 21: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

L - Land Inheritance (4)

Taacutec giả Lăng Trung Hiếu

Lời giải Nguyễn Thagravenh Trung - RR

Đặt P lagrave mảnh đất Bước 1 Dugraveng đường thẳng d cắt P thagravenh 2 phần A vagrave B Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 2 Đặt A lagrave đối xứng của A qua đường thẳng d (magraveu xanh laacute)

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 22: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

Bạn coacute thể tham khảo cagravei đặt ở Notebook của RR Bước 3 Dễ thấy kết quả bagravei toaacuten chiacutenh lagrave diện tiacutech của phần giao của A vagrave B (magraveu xanh da trời)

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 23: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

Do A vagrave B khocircng phải đa giaacutec lồi necircn việc tigravem phần giao của A vagrave B rất khoacute tuy nhiecircn nếu chỉ muốn tiacutenh diện tiacutech thigrave đơn giản hơn rất nhiều Trước hết ta hatildey xem caacutech tiacutenh diện tiacutech coacute dấu của một đa giaacutec bất kỳ

Đặt O lagrave một điểm bất kỳ trecircn mặt phẳng (thocircng thường ta lấy O lagrave gốc toạ độ để cagravei đặt đơn giản)

Diện tiacutech coacute dấu của đa giaacutec A = A 1A2An = tổng diện tiacutech coacute dấu của n tam giaacutec OAiA(i+1) Ta coi A(n+1) = A1

Đacircy chiacutenh lagrave lyacute do ta coacute thể tiacutenh diện tiacutech đa giaacutec bất kỳ theo cocircng thức 05 tổng (A(i)xA(i+1)y - A(i+1)xA(i)y)z

Viacute dụ

Diện tiacutech coacute dấu tứ giaacutec ABCD (magraveu đỏ) = (Diện tiacutech OAB) + (Diện tiacutech OBC) + (Diện tiacutech OCD) + (Diện tiacutech ODA)

Ở đacircy O -gt A -gt B O -gt C -gt D vagrave O -gt D -gt A coacute caacutec đỉnh ngược chiều kim đồng hồ necircn 3 tam giaacutec OAB OCD vagrave ODA coacute diện tiacutech dương O -gt B -gt C coacute caacutec đỉnh theo chiều kim đồng hồ necircn tam giaacutec OBC coacute diện tiacutech acircm ABCD coacute caacutec đỉnh ngược chiều kim đồng hồ necircn coacute diện tiacutech dương Quay trở lại bagravei toaacuten để tiacutenh diện tiacutech phần giao của 2 đa giaacutec A vagrave B ta cũng lagravem tương tự

Lấy 1 điểm O bất kỳ Xeacutet caacutec tam giaacutec OAiA(i+1) vagrave caacutec tam giaacutec OBjB(j+1) Thay vigrave tiacutenh phần giao của 2 đa giaacutec ta sẽ tiacutenh phần giao của caacutec tam giaacutec OA iA(i+1) với

caacutec tam giaacutec OBjB(j+1) Sau đoacute cộng tổng caacutec diện tiacutech caacutec phần giao lại

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)

Page 24: ACM ICPC HCMC 2017 Editorial - icpcvn.github.io

Chuacute yacute Ta đang lagravem việc với cả caacutec tam giaacutec acircm vagrave dương Khi tiacutenh tổng diện tiacutenh phần giao

Nếu 2 tam giaacutec dương ta coi phần giao coacute diện tiacutech dương Nếu 2 tam giaacutec acircm ta coi phần giao coacute diện tiacutech dương Nếu 1 tam giaacutec acircm vagrave 1 tam giaacutec dương phần giao coacute diện tiacutech acircm

Để tigravem giao của 2 tam giaacutec ABC vagrave XYZ ta lần lượt dugraveng 3 cạnh của XYZ cắt tam giaacutec ABC

Lấy đường thẳng XY cắt ABC thagravenh 2 phần giữ lại phần cugraveng phiacutea với Z gọi lagrave S1

Lấy đường thẳng YZ cắt S1 thagravenh 2 phần giữ lại phần cugraveng phiacutea với X gọi lagrave S2

Lấy đường thẳng ZX cắt S2 thagravenh 2 phần giữ lại phần cugraveng phiacutea với Y gọi lagrave S3

S3 chiacutenh lagrave phần cần tigravem (Phần nagravey ta sử dụng lại code lấy 1 đường thẳng cắt 1 đa giaacutec Notebook của

RR) Đến đacircy bagravei toaacuten đatilde được giải quyết với độ phức tạp O(N^2)