Mọi người giúp em bài này với ạ

Một dãy gồm N số được gọi là tốt nếu có một giá trị xuất hiện nhiều hơn N/2 lần.

Cho dãy gồm n số có giá trị trong đoạn [1,K], đếm số lượng dãy con gồm các phần tử liên tiếp của dãy đã cho là một dãy tốt.

N, K <= \(5.10^5\)

 

Dãy con có liên tiếp không bạn?

Xây dựng 1 cái vector d. d[x] lưu tập các chỉ số x trong a tăng dần, Duyệt rồi chặt đếm thôi. dpt O(nlogn) chắc vẫn qua :D

 

cho mình hỏi ở đây dãy con tốt có nghĩa là trong dãy con đó xuất hiện 1 giá trị nhiều hơn N/2 lần hay là trong dãy con đó xuất hiện 1 giá trị nhiều hơn (độ dài dãy con ) div 2

Trả lời quochuu_96
  Hiện bài gốc

Dãy con liên tiếp anh ơi

Trả lời hmh100298
  Hiện bài gốc

Trong dãy có một giá trị xuất hiện nhiều hơn độ dài dãy con / 2 lần bạn ơi

Trả lời mikelhpdatke
  Hiện bài gốc

Bạn nói rõ hơn làm thế nào mà nlogn nhỉ, mình chưa hình dung được

Trả lời freshman
  Hiện bài gốc

Giả sử có 1 vecor x lưu tập các chỉ số mà x xuất hiện hiện trong dãy a[]

Với mỗi cặp  chỉ số trong x thì có 1 dãy con, nếu dãy con này thỏa thì có nghĩa là có thể tồn tại dãy con mới bằng cách mở rộng sang trái hoặc phải của dãy con cũ. Vì số lượng só cặp tỷ lệ nghịch với số phân tử khác nhau của a[] nên mình nghĩ là qua. Còn đây chắc chưa phải cách tối ưu

Trả lời mikelhpdatke
  Hiện bài gốc

nếu dãy chỉ gồm 1 1 1 1 1... mà bạn duyệt tất cả các cặp thì tle chứ nhỉ

Theo mình thì làm thế này. Với mỗi giá trị. Mình đếm số dãy tốt với giá trị xuất hiện nhiều hơn n/2 lần là giá trị đó, rồi sau đó cộng lại.

Giờ với bài toán nhỏ hơn. Cho dãy a gồm n phần tử, đếm số dãy có giá trị T xuấn hiện hơn n/2 lần:

- Đầu tiên, với giá trị nào = x thì gán nó lại thành 1. Giá trị nào khác x thì gán thành -1. Bài toán trở thành đếm số dãy con có tổng lớn hơn 0.

- Cập nhật cây bit để tính tổng.

- Gọi số số 1 của dãy này là H, bạn chạy con trỏ i từ trái qua, để đếm số dãy tốt kết thúc tại i bằng bit. Nếu vị trí nào mà có dãy tốt thì tăng i lên 1. Không có thì di chuyển i đến vị trí phía sau gần i nhất có giá trị là 1. Như vậy thì ta có thể chứng minh luôn được là số lần i di chuyển không quá 2*H.

- Độ phức tạp của bài toán con là 2*H*log.

- Kết hợp lại thì ta sẽ có thuật giải n*log. 

- Lưu ý là bước chuyển từ bài toán này sang bài toán kia. Bạn ko chạy lại hoàn toàn bước 1 và 2 mà chỉ chạy lại trên các vị trí thay đổi. Nên chi phí chuyển cũng là n log luôn. 

Trả lời quochuu_96
  Hiện bài gốc

Hihi cảm ơn anh nhiều

Trả lời quochuu_96
  Hiện bài gốc

Mình dùng danh sách liên kết để chạy theo giá trị T (T=1..k) đúng không anh?

Còn chỗ cập nhật cây bit thì làm thế nào ạ?

Trả lời anhvu_cbl
  Hiện bài gốc

Bạn có thể dùng dslk hoặc vector hoặc gì cũng được để lưu lại các vị trí có cùng giá trị.

Cập nhật cây bit thì cập nhật như bình thường thôi. for(int i=vt; i<=n; i+=i&(-i)) capnhat();

Vấn đề ở chỗ chỉ có 1 số vị trí thay đổi thôi, nên bạn cứ chạy qua các vị trí có giá trị bị thay đổi để cập nhật lại cây bit thôi