權值線段樹只是節點存的內容變成了權值,區間,區間和,區間數字個數等,和一般線段樹的操作差別不大
但對於某些特定問題來說操作很簡便,值域較大時一般會採用離散化(就只能離線了
可求區間第k大數,逆序對個數等
示例如圖:
//待新增
結構體存
structnode
tree[n*4]; //開4倍空間
建樹
voidbuild(ll l, ll r, ll now)
ll mid=(l+r)>>1
; build(l,mid,now
<<1
); build(mid+1,r,now<<1|1
); //左右遞迴建樹
return
;}
插入新點(根據不同問題修改
voidupdate(ll pos, ll now) //pos為下標,b[pos]存值
if(pos<=tree[now<<1].r) update(pos,now<<1
);
else update(pos,now<<1|1
); tree[now].s=tree[now<<1].s+tree[now<<1|1
].s;
tree[now].num=tree[now<<1].num+tree[now<<1|1
].num;
return
;}
查詢(根據不同問題修改
ll query(ll now, ll k) //查詢求和<=k的最大個數
初始資料處理
for(i=1; i<=n; i++)sc(a[i]), b[i]=a[i];
sort(b+1,b+1+n);//需排序
build(
1,unique(b+1,b+n+1)-(b+1),1
);//unique去重,初始建樹
ll pos=lower_bound(b+1,b+n+1,a[i])-b;//二分查詢位置( -(b+1)+1=-b )
update(pos,
1);
權值線段樹
維護全域性的值域資訊,每個節點記錄的是該值域的值出現的總次數。使用二分的思想 離散化的時候,需要用到 支援查詢全域性k小值,全域性rank,前驅,後繼等。單詞操作時間複雜度為o logn 空間複雜度為o n 相對於平衡樹的優勢 簡單,速度快 劣勢 值域較大時,我們需要離散化,變成離線資料結構 我認為...
權值線段樹
include using namespace std int n,m,tre 10003 4 laz 10003 4 void pushdown int num void update int num,int le,int ri,int x,int y,int z pushdown num int...
權值線段樹
權值線段樹是線段樹的一種,但是它與線段樹不同 線段樹的每個結點是用來維護一段區間的最大值或總和 而權值線段樹的每個結點儲存的一段區間有多少個數 權值線段樹主要用來查詢區間第k大或者第k小的值 現在有乙個陣列x 10 對陣列排序後為x 10 每個數的個數如下 1 32 2 3 24 1 5 18 1 ...