樹狀陣列的奇妙應用,99 的人都不知道!

2021-08-20 20:48:57 字數 1117 閱讀 2469

提到樹狀陣列,大多數人的印象是只能求區間的字首和。然而,樹狀陣列還有很多其他的用法,用來替代線段樹可有效降低空間複雜度和**長度。

貼乙份字首和**以供參考。

int c[maxn];

int n;//可能的下標最大值

int lowbit(int x)

void add(int p,int v)//修改單點

}int prefix_sum(int p)//字首和

return sum;

}

只要把修改操作和查詢操作的遍歷順序反過來,就可以儲存字尾資訊!

原理是c[i]現在儲存從i往後數lowbit(i)個位置的資訊

void add(int p,int v)

}int suffix_sum(int p)

return sum;

}

這個實用性並沒有想象中的大,因為所有字尾資訊問題都可以轉換成字首問題。

以維護最大值為例

void insert(int p,int v)

}int prefix_max(int p)

return sum;

}

因為最值不滿足區間可減性(已知(a,b)和(a,c)的答案不能得出(b,c)的答案),所以只能求字首的最大值,是不能像線段樹一樣任意求出(l,r)的最值的。和線段樹一樣,不能修改。

分析c[i]的實際意義:從c[i]往前數lowbit(i)個的和。lowbit是二進位制最後乙個1代表的大小,因此我們可以按位討論第k大數的位置,複雜度o(logn),並不是必須外層二分套裡面的查字首和

int base;

void init()

void insert(int p)

}int kth(int k)

}return p+1;

}

這個只能求所有資料中的第k大,不如線段樹靈活。權值線段樹可以自定義l,r求

l<

x<

r l

<

x<

r的第k大的數。而相比於靜態的二分,它的優點是可以隨時插入和刪除元素。這有效填補了set功能中的乙個空白。

99 的人都不知道的90個秘密

1.拉斯維加斯的賭場都沒有鐘。2.麥當勞 40 的利潤來自 的銷售。3.1996 版的韋伯斯特詞典有 315處拼寫錯誤。4.每天平均有 12個新生兒被交給錯誤的父母。5.巧克力對於狗來說是致命的,只要幾盎斯就可以使乙隻小狗,因為心臟和神經系統受損而死亡。6.19 世紀30 年代番茄醬是作為藥品來銷售...

樹狀陣列的應用

樹狀陣列的應用1 求逆序數 首先考慮將輸入陣列離散化,因為題目要求輸入的數值可以達到10的9次方,肯定不會開出那麼大的陣列。1.定義乙個結構體 val儲存原值,pos儲存原來在陣列中的位置 2.在對原結構體陣列對val值排序 3.定義儲存離散化資料的陣列flect,flect node i pos ...

樹狀陣列的應用

include include define lowbit i i i const int maxn 100010 int c maxn 樹狀陣列 getsum函式返回前x個整數之和 int getsum int x return sum 返回和 update函式將第x個整數加上v void upd...