值域線段樹and動態開線段樹

2022-05-20 21:09:09 字數 1334 閱讀 6763

值域線段樹每乙個節點代表乙個值,其他沒什麼區別

動態開樹就是節省了沒有用到節點,其中重要一點的是不需要節點是連續的(即id值是任意的,只要可以找到即可)

例題

bzoj 4627迴轉壽司

題意

給n個數問區間和在l<=sum【r】-sum【l-1】<=r區間有多少個

(n≤100000,|ai|≤100000,0≤l, r≤10^9)

分析

由於區間和不單調,所以不能二分求取,分析可得推出公式   sum(r)-r<=sum(l-1)<=sum(r)-l  ([l,r]是乙個滿足條件的區間)

直接計算當前字首和之前滿足條件的字首和個數,累加起來則為答案

故考慮利用線段樹,每次讓對應的字首和加1,然後統計滿足條件的個數,但是這個數最大可以達到1e10,不可能開這麼大的空間,

但n最大10w,和的種類也就10w,故考慮動態開線段樹,每次只開根到這個節點上路徑上經過的點,這樣最多開log(n)*n即可,

這樣的話每次必須儲存當前節點的左右兒子的id才可以準確訪問左右兒子,其他和線段樹差不多

trick:注意開始要處理sum,這樣才可以保證當l==r時滿足條件也能被統計上

#include#define ll long long

using

namespace

std;

const

int maxn = 1e7 + 10

;ll tree[maxn], lson[maxn], rson[maxn];

ll tot;

ll a[

100005

];ll sum[

100005

];const ll inf =1e10;

intn;

ll root=1

;int

newnode()

void update(ll &x, ll l, ll r, ll val)

ll query(ll x, ll l, ll r, ll ql, ll qr)

intmain()

ll ans=0

; update(root, -inf, inf, 0

);

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

printf(

"%lld\n

", ans);

return0;

}

view code

主席樹 可持久化值域線段樹

主席樹是可持久化的線段樹,其最大的優點就是在消耗記憶體較少的情況下保證了線段樹的結構。那麼什麼是主席樹呢?對於區間 1,n 對於每乙個子區間 1,i 建立一棵線段樹 1 i n 線段樹的每乙個節點存某個字首 1.i 中屬於區間 l.r 的數一共有多少個,這就是一顆主席樹。如果我們對於每乙個區間都建一...

題解 A君的問題 a (值域線段樹)

這道題很水,但不要問ssw02為什麼要在這時做一道b層的題 因為ssw02再換板子,而這道題就是二分值域線段樹的裸題 感謝神犇sxk提供優質的模板參考 題目描述 a君來到了乙個蛋糕店,蛋糕店有n個位置順次擺放著若干蛋糕,從左到右位置編號依次遞增。當有客人來的時候服務生會把有些位置的蛋糕打包給客人,也...

線段樹動態開點

為了降低權值線段樹的空間複雜度,可以不直接建出整棵線段樹的結構,而是在最初只建立乙個根節點,當需要訪問某棵為建立的子樹的時候,再建立代表這個子樹的節點。動態開點的線段樹用變數記錄左右節點的編號。值域為1 n的動態開點線段樹在m次單點修改後,節點規模為o mlogn 例題 p1908 逆序對 這題n最...