1. Trang chủ
  2. » Luận Văn - Báo Cáo

CHUYÊN đề cây QUẢN lý đoạn

22 380 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 22
Dung lượng 381,49 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Điều này làm cho cây quản lý đoạn chỉ giống với segment trees ở hình ảnhbiểu diễn còn các thuộc tính và phương thức trở nên đơn giản và “yếu” hơn nhiều sovới cấu trúc nguyên thủy, theo n

Trang 2

CÂY QUẢN LÝ ĐOẠN

Segment trees là một cấu trúc dữ liệu ban đầu được thiết kế cho các ứng dụng

hình học Cấu trúc này khá phức tạp và được sử dụng để trả lời nhiều loại truy vấn

khó Segment trees thường được so sánh với interval trees là một dạng cấu trúc dữ

liệu khác cũng cung cấp các chức năng tương đương

Trong mục này, ta đơn giản hóa cấu trúc segment trees để giải quyết bài toán truy vấnphạm vi Điều này làm cho cây quản lý đoạn chỉ giống với segment trees ở hình ảnhbiểu diễn còn các thuộc tính và phương thức trở nên đơn giản và “yếu” hơn nhiều sovới cấu trúc nguyên thủy, theo nghĩa không trả lời được những truy vấn khó như cấutrúc nguyên thủy

Trên các diễn đàn thảo luận về thuật toán, đôi khi tên gọi interval trees hoặc segmenttrees vẫn được dùng để gọi tên cấu trúc này Các bài giảng thuật toán cũng chỉ dùngtên gọi interval trees và segment trees để đề cập tới hai cấu trúc dữ liệu trong hình họctính toán Cấu trúc cây quản lý đoạn, chỉ là một hạn chế của interval trees haysegment trees trong trường hợp cụ thể

Cấu trúc cây quản lý đoạn cung cấp một cách quản lý mới thông qua các đoạn sơ cấp,ngoài ra việc cài đặt dễ dàng cũng là một ưu điểm của cấu trúc dữ liệu này

1 Cấu trúc cây quản lý đoạn

Cây quản lý đoạn là một cây nhị phân đầy đủ (full binary trees) có cấu trúc như sau:

- Mỗi nút quản lý một dãy các đối tượng liên tiếp, trong nút chứa thông tin tổnghợp từ các đối tượng mà nó quản lý

- Nút gốc quản lý các đối tượng từ 1 tới n

- Nếu một nút quản lý dãy các đối tượng từ l tới r (l<r) thì nút con trái của nóquản lý các đối tượng từ l tới m và nút con phải của nó quản lý các đối tượng từm+1 tới r Ở đây m = (l+r) div 2

- Nếu một nút chỉ quản lý một đối tượng thì nó sẽ là nút lá và không có nút con.Trong một số trường hợp cần tăng tốc thuật toán, mỗi đối tượng sẽ được gắnvới một con trỏ leaf[i] trỏ tới nút lá quản lý trực tiếp đối tượng i

Trang 3

2 Biểu diễn cây quản lý đoạn

Ta biểu diễn cây bằng mảng một chiều Nút số 1 là nút gốc, nút x không phải lànút lá sẽ có nút con trái là nút 2x , nút con phải là nút 2x+1 và nút cha là nút x div 2

Một vấn đề đặt ra là với một đoạn gồm n phần tử (1 n) thì mảng một chiều biểudiễn cây cần phải có bao nhiêu phần tử là đủ, người ta đã chứng minh chỉ số các nút trong cây

không vượt quá 4n-3 Do đó để dễ nhớ người ta thường khai báo mảng với các phần

tử được đánh số từ 1 tới 4n

Ta có nút 1 quản lý các đối tượng từ 1 tới n Vậy nút 2 quản lý các đối tượng từ

1 tới n div 2, nút 3 quản lý các đối tượng từ n div 2 +1 tới n Tương tự như vậy vớimột nút k nào đó ta sẽ xác định được đoạn mà k quản lý

3 Cài đặt cây quản lý đoạn

Cây quản lý đoạn có 3 thao tác chính:

Build: Xây dựng cây

Update: Cập nhật thông tin cho đoạn

Query: Truy vấn thông tin của đoạn

Để khảo sát cấu trúc dữ liệu và vận dụng cây quản lý đoạn, ta sét các ví dụ sau

3.1 Trường hợp biến đổi một phần tử

Ví dụ:

Cho một dãy gồm n số nguyên A=(a1, a2, , an)

Xét hai phép biến đổi:

- Phép cập nhật Update(i,v): Đặt ai :=v

- Phép truy vấn Query(i,j): Trả về tổng các phần tử từ ai tới aj

Trang 4

Yêu cầu: Cho dãy thao tác thực hiện tuần tự, hãy trả lời tất cả các truy vấn Query

Sử dụng mảng T lưu trữ cây quản lý đoạn T[k] là tổng giá trị của đoạn mà nút k quảnlý

Xây dựng cây quản lý đoạn

procedure Build(k: longint; l,r: longint);

Trang 5

Build(2*k + 1, (l+r) div 2 + 1, r);

T[k] := T[2 * k] + T[2 * k + 1];

end;

Thủ tục khởi tạo cây quản lý đoạn sẽ được thực hiện bằng lời gọi Build(1,1,n)

Cập nhật thông tin cho đoạn

Mỗi khi có sự thay đổi giá trị phần tử ta cần phải cập nhật lại cây Khi một phần

tử ai bị thay đổi, ta nhảy tới nút k là nút lá trực tiếp quản lý ai, thay T[k] = ai và cập nhật lại thông tin tổng T[ ] cho tất cả các nút chứa phần tử ai trong phạm vi quản lý

procedure Update(k,l,r: longint; i,v: longint);

var x: longint;

begin

if (l>r) or (l>i) or(r<i) then exit;

if( l=i) and (r=i) then

Update(2 * k, l, mid, i,v);

Update(2 * k+1,mid+1, r, i,v);

T[k] := T[2*k] + T[2*k+1] ;

end;

Thủ tục cập nhật thông tin cho đoạn sẽ được thực hiện bằng lời gọi Update(1,1,n,i,v)

Truy vấn thông tin của đoạn

Phép truy v n nh n vào hai ch s i ≤ j và tr v t ng các ph n t t aấn nhận vào hai chỉ số i ≤ j và trả về tổng các phần tử từ a ận vào hai chỉ số i ≤ j và trả về tổng các phần tử từ a ỉ số i ≤ j và trả về tổng các phần tử từ a ố i ≤ j và trả về tổng các phần tử từ a ả về tổng các phần tử từ a ề tổng các phần tử từ a ổng các phần tử từ a ần tử từ a ử từ a ừ a i t i ới

aj

Đ truy v n v t ng các ph n t t aể truy vấn về tổng các phần tử từ a ấn nhận vào hai chỉ số i ≤ j và trả về tổng các phần tử từ a ề tổng các phần tử từ a ổng các phần tử từ a ần tử từ a ử từ a ừ a i t i aới j, ta th c hi n truy v n các ực hiện truy vấn các ện truy vấn các ấn nhận vào hai chỉ số i ≤ j và trả về tổng các phần tử từ a

ph n t n m trong đo n mà nút k qu n lý Khi đó ta xét các trần tử từ a ử từ a ạn mà nút k quản lý Khi đó ta xét các trường hợp sau: ả về tổng các phần tử từ a ường hợp sau:ng h p sau:ợp sau:

- Trường hợp 1: [l r]  [ i j] = , nút k không quản lý đối tượng nào trongphạm vi truy vấn, hàm Query trả về 0

- Trường hợp 2: [l r] [ i j], tất cả các đối tượng do nút k quản lý đều nằmtrong phạm vi truy vấn, hàm Query trả về T[k]

- Ngoài hai trường hợp trên, hàm Query gọi đệ quy để “hỏi” hai nút con vềtổng các phần tử truy vấn thuộc phạm vi quản lý của nhánh con trái và tổng các

Trang 6

phần tử truy vấn thuộc phạm vi quản lý của nhánh con phải, sau đó cộng hai kếtquả lại thành kết quả hàm.

function Query(k,l,r: longint; i, j: Integer): Int64;

q1:= Query(2 * k, l, mid, i,j);

q2:= Query(2 * k+1,mid+1, r, i,j);

exit(q1+q2);

end;

Thủ tục truy vấn thông tin của đoạn sẽ được thực hiện bằng lời gọi Query(1,1,n,i,j)

3.1 Trường hợp biến đổi một dãy phần tử

Trong trường hợp này chúng ta không cập nhật từ nút lá lên nút gốc mà cậpnhật từ nút gốc xuống nút lá Do đó khi cập nhật thông tin cho một nút k ta phải cậpnhật thông tin lại cho tất cả các nút là hậu duệ của k mà việc làm này rất tốn thời gian

và ảnh hưởng đến tốc độ của thuật toán

Để đảm bào thời gian thực hiện thuật toán là tối ưu đối với phép cập nhật khi có

sự biến đổi trên một dãy phần tử thì người ta sử dụng phương pháp truyền lười (Lazy

Propagation) Trong phương pháp truyền lười sử dụng cờ Lazy để ghi nhớ thông tincần cập nhật của một nút Lazy[k] ghi nhớ thông tin cần cập nhật của nút k

Ý tưởng của phương pháp truyền lười như sau:

Phép toán cập nhật thông tin cho nút k, Update(k):

- Cập nhật thông tin Lazy[k] cho nút k, không cập nhật thông tin Lazy[k]cho cac nút là hậu duệ của k nhưng phải ghi nhớ thông tin Lazy[k] qua 2

cờ Lazy[2*k] và Lazy[2*k+1] để cập nhật lại cho cac nút là hậu duệ của

k ở phép toán Query

- Nếu nút k quản lý đoạn nằm trong đoạn cần cập nhật thì cũng chỉ cậpnhật thông tin cho nút k, không cập nhật cho cac nút là hậu duệ của knhưng phải ghi nhớ thông tin cập nhật qua 2 cờ Lazy[2*k] vàLazy[2*k+1] để cập nhật lại cho cac nút là hậu duệ của k ở phép toánQuery

Chính vì không cập nhật cho cac nút là hậu duệ của k đã làm giảm đáng kể thờigian thực hiện của phép toán Update

Phép toán truy vấn thông tin của nút k, Query(k):

- Cập nhật thông tin Lazy[k] cho nút k

Trang 7

- Truy vấn thông tin nút k

Ví dụ:

Cho một dãy gồm n số nguyên A=(a1, a2, , an)

Xét hai phép biến đổi:

- Phép cập nhật Update(i,j, v): Tăng các phần tử từ ai đến aj thêm giá trị v

- Phép truy vấn Query(i,j): Trả về tổng các phần tử từ ai tới aj

Yêu cầu: Cho dãy thao tác thực hiện tuần tự, hãy trả lời tất cả các truy vấn Query

Sử dụng mảng T lưu trữ cây quản lý đoạn T[k] là tổng giá trị của đoạn mà nút k quảnlý

Sử dụng mảng Lazy ghi nhớ thông tin cần cập nhật Lazy[k] là thông tin cần cập nhật của nút k

Xây dựng cây quản lý đoạn

procedure Build(k: longint; l,r: longint);

begin

if ( l>r) then exit;

Trang 8

Thủ tục khởi tạo cây quản lý đoạn sẽ được thực hiện bằng lời gọi Build(1,1,n)

Cập nhật thông tin cho đoạn

procedure update(k, l, r:longint; i, j, x:longint);

if ( l> r) or(l>j) or(r<i) then exit;

if (i<=l) and (r<=j) then

Trang 9

Truy vấn thông tin của đoạn

function query(k,L,R:longint; i,j:longint):longint;

if (l>r)or(L>j) or (r<i) then exit(0);

if (i<=L) and (r<=j) then exit(t[k]);

Trang 10

Bác John đã chuẩn bị một danh sách gồm Q (1 ≤ Q ≤ 200000) đoạn các con bò vàchiều cao của chúng (trong phạm vi [1, 1000000]) Với mỗi đoạn, bác John muốn xácđịnh chênh lệch chiều cao giữa con bò thấp nhất và cao nhất Bạn hãy giúp bác Johnthực hiện công việc này!

Dữ liệu

- Dòng đầu tiên chứa 2 số nguyên N và Q

- Dòng thứ i trong số N dòng sau chứa 1 số nguyên duy nhất, là độ cao của con

bò thứ i

- Dòng thứ i trong số Q trong tiếp theo chứa 2 số nguyên A, B (1 ≤ A ≤ B ≤ N),cho biết đoạn các con bò từ A đến B

Kết qủa

- Gồm Q dòng, mỗi dòng chứa 1 số nguyên, là chênh lệch chiều cao giữa con

bò thấp nhất và cao nhất thuộc đoạn tương ứng

Ví dụ

INPUT

OUTPUT

6 3173425

1 5

4 6

2 2

630

Code chương trình tham khảo

const

fi=''; fo=''; maxn=5*round(1e4)+1; vc=round(1e9);

var

a: array [1 maxn+1] of longint;

Tmax, Tmin: array [1 4*maxn+1] of longint;

Trang 11

procedure Query(k,l,r:longint; i,j: longint; var maxx,minn: longint);

var qma1,qma2,qmi1,qmi2, mid:longint;

Trang 12

Q x y, 1 ≤ x < y ≤ N: Tìm hai chỉ số i, j mà x ≤ i < j ≤ y sao cho tổng a[i]+a[j] là lớn nhất, ghi ra tổng a[i]+a[j]

Trang 13

+ Nếu ký tự đầu dòng là “Q” thì tiếp theo là hai số nguyên x, y tương ứng với phép truy vấn Query

Output

Trả lời tất cả các truy vấn , với mỗi truy vấn in ra câu trả lời trên 1 dòng

Ví dụ:

Input Output5

1 2 3 4 5

Code chương trình tham khảo

a: array [0 maxn] of longint;

t: array [0 4*maxn] of nut;

Trang 14

if (l>r) or (r<i) or (l>i) then exit;

if (l=i) and (r=i) then

if (l>r) or (r<i) or (l>j) then exit(vc);

if (i<=l) and (r<=j) then exit(t[k]);

Trang 15

if c='U' then update(1,1,n,x,y) else

begin nhat:=Query(1,1,n,x,y);

Bài 3 Giá trị lớn nhất (QMAX)

Cho một dãy gồm n phần tử có giá trị ban đầu bằng 0

Cho m phép biến đổi, mỗi phép có dạng (u, v, k): tăng mỗi phần tử từ vị trí u đến vị trí v lên k đơn vị

Cho q câu hỏi, mỗi câu có dạng (u, v): cho biết phần tử có giá trị lớn nhất thuộcđoạn [u, v]

Giới hạn

Trang 16

n, m, q <= 50000

k > 0Giá trị của một phần tử luôn không vượt quá 231-1

Trang 17

if ( l> r) or(l>j) or(r<i) then exit;

if (i<=l) and (r<=j) then

Trang 18

if (l>r)or(L>j) or (r<i) then exit(0);

if (i<=L) and (r<=j) then

Bài 4 Giá trị lớn nhất ver2 (QMAX2)

Cho một dãy gồm n phần tử có giá trị ban đầu bằng 0

Cho m phép biến đổi và câu hỏi, mỗi phép biến đổi có dạng (u, v, k): tăng mỗi phần tử từ vị trí u đến vị trí v lên k đơn vị, mỗi câu hỏi có dạng (u, v): cho biết phần tử có giá trị lớn nhất thuộc đoạn [u, v]

Input

Trang 19

- Dòng 1 chứa 2 số nguyên dương n, m (n <= 50000, m <= 100000)

- m dòng tiếp, mỗi dòng cho thông tin về một phép biến đổi hoặc một câu hỏi

+ Phép biến đổi có dạng: 0 u v k ( 0< k ≤ 231-1)+ Câu hỏi có dạng : 1 u v

0 4 6 4

Trang 20

lazy[2*k +1]:= lazy[2*k +1]+lazy[k];end;

lazy[k]:=0;

end;

if ( l> r) or(l>j) or(r<i) then exit;

if (i<=l) and (r<=j) then

Trang 21

if (i<=L) and (r<=j) then

else

begin

kq:=query(1,1,n,u,v); writeln(g,kq);

Trang 22

Vậy Cấu trúc cây quản lý đoạn cung cấp một cách quản lý mới thông qua các

đoạn sơ cấp, ngoài ra việc cài đặt dễ dàng cũng là một ưu điểm của cấu trúc dữ liệunày

Cây quản lý đoạn dựa trên thuật toán tìm kiếm nhị phân, nên sử dụng cây đặcbiệt này quá trình thực hiện thuật toán đạt hiệu quả cao

Ngày đăng: 03/01/2016, 21:34

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w