RMQ的兩種實現方法

2021-08-10 00:21:20 字數 1421 閱讀 5214

st表實現rmq

rmq演算法(range minimum/maximum query) 是求區間極值的高效演算法,依據所需實現的不同效能可以有多種寫法,這裡主要講基於線段樹和稀疏表(sparse table)的兩種方法

線段樹是維護區間的一類高效資料結構,依據這個特性,我們可以用線段樹實現rmq演算法,用線段樹實現的rmq演算法不僅可以查詢區間最小值,還可以更改某個節點的值

#include

using

namespace

std;

typedef

long

long

int ll;

const

int maxn=18;

const

int inf=1e9;

int num[2*(1

void init(int base)

for(int i=0;i<2*n-1;i++)

}void change_k(int k,int a)

}int get_min(int a,int b,int k,int l,int r)

}int main()

int a,b;

scanf("%d %d",&a,&b);

/*int k,num;

scanf("%d %d",&k,&num);

change_k(k,num);

這裡還可以實現更改

*/printf("%d\n",get_min(a,b,0,0,n)==inf?-1:get_min(a,b,0,0,n));

}

預處理時,操作的節點個數為n+n/2+n/4+……,約為2n個,所以複雜度為o(n),每一次查詢與修改區間值的複雜度是o(log n).

線段樹的查詢複雜度為o(log n),對於有多組詢問的題還是太慢,有了線段樹實現的鋪墊,我們思考,是否有一種方法能預先處理出區間極值呢,答案是有的,就是st表

#include

using

namespace

std;

const

int maxn=18;

int dp[(1

void st_init()

for(int j=1;(1

<1],dp[i+(1

<<(j-1))][j-1]);}}

}int get_min(int l,int r)

int main()

st_init();

int l,r;

scanf("%d %d",&l,&r);

printf("%d\n",get_min(l,r));

}

顯而易見,預處理時的複雜度是o(n log n)的,而查詢的複雜度為o(1),可以高效解決多組詢問的題目,但基於st表的寫法無法對區間的值進行高效更新.

List排序的兩種實現方法

利用collections.sort方法可以對列表進行排序collections有兩個sort方法 1.sort listlist 2.sort listlist comparator c 方法一 只需要傳入乙個list即可,但是該list中的元素需要實現comparable介面,覆蓋compare...

屬性動畫的兩種實現方法

方法一 根據資料processlist解析出 totaltime,使用 animatorset 來組合動畫,並把每一組動畫加入animations 進行管理。private float totaltime 0 private listanimations new arraylist private ...

多執行緒的兩種實現方法

單執行緒 安全性高,效率低 多執行緒 安全性低,效率高 一 多執行緒的第一種實現方式 建立乙個繼承thread的類,實現run 方法,然後在另乙個類中建立該類的物件,通過物件去呼叫多執行緒中的方法。如下 1.建立繼承thread的類 package test1 public class mythre...