poj 2104為例【經典劃分樹問題】
思想:利用快速排序思想,
**:
#include
#include
using
namespace
std;//
const
int maxn = 100010;
int tree[20][maxn];//每層每個位置的值
int sorted[maxn];//排好序的陣列,方便尋找中值
int leftsum[20][maxn];//有多少個數分到該層該位置左邊
void build(int p, int l, int r)
//與中值相等的數填滿區間一半
int tl = l, tr = mid + 1;
for(int i = l; i <= r; i++)else
tree[p + 1][tr++] = tree[p][i];
leftsum[p][i] = leftsum[p][l-1] + tl - l;
}build(p + 1, l, mid);
build(p + 1, mid + 1, r);
}//[l,r]中的[l,r]的第k大數
int query(int l, int r, int l, int r, int p, int k)
else
}int main (void)
sort(sorted+1, sorted+n+1);
build(0, 1,n);
int s, t, k;
while(m--)
return
0;}
劃分樹還是挺好理解的,接下來看看歸併樹和主席樹。 快樂找到區間第K大 劃分樹
劃分樹,顧名思義就是將乙個序列,劃分成很多小部分。其作用就是可以快樂地找到給定區間第k大的數。其實使用歸併樹和快排也都可以找到區間內第k大的數,但其效率都不如劃分樹要好,快排過的時間複雜度o n x m 而劃分樹是o n x logn 劃分樹原理 1.建樹 根結點就是原序列,左孩子儲存父結點所有元素...
區間第k大(主席樹)
學了一下主席樹模板題,當初看了網上的主席樹講解都沒有看懂,後面看了嗶哩嗶哩的uestc的主席樹,終於看懂了思想。每次更新的複雜度都為logn。每次更新的話就是對要更新的點路徑上的點重新更加乙個,然後進行對沒有影響的那些進行連邊。然後用乙個root記錄每乙個線段樹的根節點下標。include incl...
主席樹區間第K大
主席樹的實質其實還是一顆線段樹,然後每一次修改都通過上一次的線段樹,來新增新邊,使得每次改變就改變logn個節點,很多節點重複利用,達到節省空間的目的。1.不帶修改的區間第k大。hdu 2665 模板題 1 include2 using namespace std 3 define fopen fr...