太難了 什麼時候站起來

2022-08-20 00:24:16 字數 1815 閱讀 5386

暫無

線段樹是所有 rmq 中最常用的資料結構。

功能:區間修改區間查詢。不止最值、求和。只要可遞推的值都可以構造線段樹。

如果區間大小為 n,線段樹有 cnt 個節點,那麼 2n−1≤cnt<4n。

節點對於每個節點 x,和堆類似,父親節點為 x>>1(即 x/2 下取整的位運算方法,位運算方便而且快),左兒子為 x<<1(即 2x),右兒子為 x<<1|1(即 2x+1)。

同時每個節點對應一段區間,所以叫線段樹。節點 1 對應的區間為 1∼n。設乙個節點對應的區間為 l∼r,那麼它的左兒子對應的區間就是 l∼mid,其中 mid=(l+r)>>1,右兒子區間為 mid+1∼r。如果乙個節點對應單點區間,就沒有兒子。

同時每個節點對應乙個值,即該區間的 rmq 值。如果是求最值問題,就表示該區間最大值;如果是求和問題,就表示該區間的和。

操作(單點修改區間查詢)

乙個線段樹是求和還是求最值或者求別的東西,取決於 pushup(k) 函式,其中 k 為節點編號,時間複雜度 o(1)。

void pushup(int k)//求最大值

根據原序列構造初始的線段樹用 build() 函式,單點節點上的值就為單點的值,遞迴從下到上構造,時間複雜度 o(nlogn)。

void build(int k=1,int l=1,int r=n) //單點節點

build(k<<1,l,mid),build(k<<1|1,mid+1,r); //遞迴構造

pushup(k); //遞推

先講單點修改(加上 y),只需與 build() 函式類似的遞迴操作即可,如果到達單點節點,就修改,不走那些跟查詢單點沒關係的區間、別忘了修改完後也要遞推,時間複雜度 o(logn)。

void fix(int x,int y,int k=1,int l=1,int r=n) //單點修改

if(mid>=x) fix(x,y,k<<1,l,mid); //遞迴左兒子

else fix(x,y,k<<1|1,mid+1,r); //遞迴右兒子

pushup(k);//遞推

區間查詢,如果單前節點在查詢區間內,就返回值。否則,遞迴左兒子右兒子,遞推得區間查詢值。時間複雜度 o(logn),因為只會走相關的 logn 個節點。

int fmax(int x,int y,int k=1,int l=1,int r=n)

void build(int k=1,int l=1,int r=n)

build(k<<1,l,mid),build(k<<1|1,mid+1,r);

pushup(k);

void fix(int x,int y,int k=1,int l=1,int r=n)

if(mid>=x) fix(x,y,k<<1,l,mid);

else fix(x,y,k<<1|1,mid+1,r);

pushup(k);

int fmax(int x,int y,int k=1,int l=1,int r=n)using namespace sumtree;

int main(){

scanf("%d%d",&n,&m);

for(int i=1;i<=n;i++)

scanf("%d",a+i);

build();

for(int i=1,x,y,z;i<=m;i++){

scanf("%d%d%d",&x,&y,&z);

if(x==1) fix(y,z);

else printf("%d\n",fmax(y,z));

return 0;

線段樹如果只能單點修改區間查詢,**還這麼長,就沒人用他了。所以可想而知,線段樹還可以區間修改,區間查詢。

什麼時候用exists 什麼時候用in

in not in exists not exists 使用exists,oracle會首先檢查主查詢,然後執行子查詢直到它找到第乙個匹配項,這就節省了時間。oracle在執行in子查詢時,首先執行 子查詢,並將獲得的結果列表存放在乙個加了索引的臨時表中。在執行子查詢之前,系統先將主查詢掛起 待子查...

什麼時候用GET?什麼時候用POST?

get和post兩種方法都是將資料送到伺服器,但你該用哪一種呢?http標準包含這兩種方法是為了達到不同的目的。post用於建立資源,資源的內容會被編入http請示的內容中。例如,處理訂貨表單 在資料庫中加入新資料行等。當請求無 時 如進行搜尋 便可使用get方法 當請求有 時 如新增資料行 則用p...

什麼時候用堆,什麼時候用棧?

參考文章 c 面試題之記憶體分配 一 首先,回顧一下c c 的記憶體分配機制。乙個c c 程式編譯時記憶體分為5大儲存區 堆區 棧區 靜態區 全域性區 文字常量區 儲存字串常量 程式 區 存放二進位制程式 下面主要闡述前面三個。1 靜態儲存區域 靜態儲存區域的 內存在程式編譯時就已經分配好,這塊內存...