ZKW線段樹之旅 1

2021-07-10 19:15:34 字數 1701 閱讀 6750

膜拜zkw神犇。。。。orz。。。

zkw線段樹的思想是直接找到乙個大區間對應的小區間

由於是自底向上的,所以常數很小(《統計的力量》)

其實我覺得,真正難寫的是區間修改

比如現在造一顆線段樹,支援區間求和,區間修改

zkw線段樹有兩種做法:

一是維護神奇的字首和的字首和

二是沿用遞迴版線段樹的思路,在區間上打標記,然後統計

太弱,第一種不會。。。於是我就用第二種吧

區間修改:簡單,就在區間上打個標記,順便更新一下遍歷到的區間和,最後當l和r父親相同時,迴圈結束,再把他們的父親們的和更新。

區間求和:先是記一下左邊右邊的區間裡有幾個元素要加,每次就根據遍歷到的區間的標記更新答案。最後當l和r父親相同時,迴圈結束,再把他們的父親們的標記拿來更新答案

好像有點大話連篇。。。上**好了

const int maxn=262144;

int sumv[maxn],addv[maxn],m;

//sumv 維護區間的和,addv是標記;m不說了吧,地球人都知道

void update(int l,int r,int a)

data[l]+=ln*a;data[r]+=rn*a;

for(ln+=rn,l>>=1;l;l>>=1)

data[l]+=ln*a;//我的父親們~

}int query(int l,int r)

sum+=addv[l]*ln+addv[r]*rn;

for(ln+=rn,l>>=1;l;l>>=1)

sum+=addv[l]*ln;//我的父親們~

return

sum;

}//ps:有錯誤就說一說啊。。。

現在,某人又要求造一顆線段樹支援區間修改,區間最小值

還是沿用區間求和的思路,只是**有點不同

對於更新最小值的操作,不能單純的加減了,而是要根據兒子的值而修改。

const

int maxn=262144;

int data[maxn],addv[maxn],m,n;

//data是區間最小

int query(int l,int r)

lmax+=addv[s];rmax+=addv[t];

lmax=min(lmax,rmax);

for(s>>=1;s;s>>=1)lmax+=addv[s];

return lmax;

}void add(int l,int r,int a)

data[t]=min(data[t<<1]+addv[t<<1],data[t<<1|1]+addv[t<<1|1]);

for(;s;s>>=1)

data[s]=min(data[s<<1]+addv[s<<1],data[s<<1|1]+addv[s<<1|1]);

}

嘿嘿嘿。。。

我的線段樹~

線段樹和zkw線段樹

好啦,我們就開始說說線段樹吧 線段樹是個支援區間操作和查詢的東東,平時的話還是蠻實用的 下面以最基本的區間加以及查詢區間和為例 線段樹顧名思義就是棵樹嘛,葉子節點是每個基本點,它們所對應的父親就是它們的和,具體如下圖 但是對於這樣的線段樹來說,操作所需的時間是遠達不到我們的要求的 會被t 因為我們會...

zkw線段樹小結

zkw zkwzk w線段樹作為迴圈式線段樹具有較小的常數.其實樹狀陣列本質上就是線段樹 下標為 1,n 1,n 1,n 預處理乙個2 k n2 k n 2k n.然後總空間為2k 12 2k 1 2 k 1 4n 2 4n 2k 1 4n 後面令k 2 kk 2 k k 2k 那麼乙個葉子x xx...

鏈結 zkw線段樹

資料結構 走近zkw線段樹 一 資料結構 走近zkw線段樹 二 線段樹的擴充套件之 zkw線段樹 include define lc x x 1 define rc x x 1 1 using namespace std const int maxn 100005 int max int a,int...