線段樹入門到自閉

2022-05-21 21:18:13 字數 3556 閱讀 2919

線段樹是一種二叉樹,也就是對於乙個線段,我們會用乙個二叉樹來表示。

可以進行一些區間的修改和查詢。

線段樹通用的build方法

void build(int k,int l,int r)

int mid=(l+r)>>1;

build(ls(k),l,mid);

build(rs(k),mid+1,r);

pushup(k);//代表更新sum,這裡可以是sum[k]=sum[(ls(k)]+sum[rs(k)]。

}

因為要進行區間的查詢和修改,線段樹還需要兩個函式,check和update。check函式和update都用到了分治的思想。

簡單的應用是區間修改+單點查詢,區間查詢+單點修改。

區間修改單點查詢的思路是將區間標記,然後查詢時從上到下加起來,直到葉子節點。區間查詢+單點修改的思路是修改時直到葉子節點。單點的操作遞迴不會出現左右都有的情況,其餘與區間操作類似。

下面的**都是都是對區間進行操作的。

int check(int k,int l,int r,int x,int y)

void add(int k,int l,int r,int x,int y,int v)

int mid=(l+r)>>1;

if(x<=mid)add(ls(k),l,mid,x,y,v);

if(y>mid)add(rs(k),mid+1,r,x,y,v);

pushup(k);

}

線段樹可以進行複雜的區間修改和區間查詢操作,主要要用到pushdown函式和懶標記。

懶標記是修改的因子,在對某個節點進行操作時,如果不需要對其兒子節點進行操作,就盡在這個節點進行懶標記,如果後邊會對兒子節點進行修改查詢操作,就要pushdown,向下傳遞懶標記。還有一些特殊的根號線段樹和除法線段樹。

題意題目要求維護區間並求區間的方差,通過化簡可以得知,求解方差只需要維護區間平方和與區間和即可。

**

int const maxn=1000005;

double sum1[maxn*2],sum2[maxn*2],tree[maxn],lazy[maxn*2];

inline int read()

while(c>='0'&&c<='9')

return x*f;

}void pushup(int k)

void build(int k,int l,int r)

int mid=(l+r)>>1;

build(ls(k),l,mid);

build(rs(k),mid+1,r);

pushup(k);

}void pushdown(int k,int l,int r)//pushdown的寫法一般是線段樹題目的核心

double check1(int k,int l,int r,int x,int y)

double check2(int k,int l,int r,int x,int y)

void add(int k,int l,int r,int x,int y,double v)

if(lazy[k])pushdown(k,l,r);//關鍵**

int mid=(l+r)>>1;

if(x<=mid)add(ls(k),l,mid,x,y,v);

if(y>mid)add(rs(k),mid+1,r,x,y,v);

pushup(k);

}main(void)

build(1,1,n);

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

if(cmd==2)

if(cmd==3)

}}

題意

簡單的區間維護

**

const int maxn=100005;

int sum[maxn*4],a[maxn],lazy[maxn*4];

void build(int k,int l,int r)

int mid=(r+l)>>1;

build(ls(k),l,mid);

build(rs(k),mid+1,r);

sum[k]=sum[ls(k)]+sum[rs(k)];

}void pushdown(int k,int l,int r)

void add(int k,int l,int r,int x,int y,int z)

if(lazy[k])pushdown(k,l,r);

int mid=(l+r)>>1;

if(x<=mid)add(ls(k),l,mid,x,y,z);

if(y>mid)add(rs(k),mid+1,r,x,y,z);

//得到子樹後加到父親節點

sum[k]=sum[ls(k)]+sum[rs(k)];

}int check(int k,int l,int r,int x,int y)

main(void)

else

} }

題意

維護區間的乘積和加法,兩個懶標記,乙個為乘積因子,乙個為加法因子

**

const int maxn=200010;

int p,a[maxn],sum[4*maxn],mul[4*maxn],add[4*maxn];

inline void qm1(int k)

inline void build(int k,int l,int r)

int mid=(l+r)/2;

build(ls(k),l,mid);

build(rs(k),mid+1,r);

sum[k]=sum[ls(k)]+sum[rs(k)];

}inline void pushdown(int k,int l,int r)

inline void add(int k,int l,int r,int x,int y,int v)

pushdown(k,l,r);

int mid=(l+r)/2;

if(x<=mid)add(ls(k),l,mid,x,y,v);

if(y>mid)add(rs(k),mid+1,r,x,y,v);

sum[k]=sum[ls(k)]+sum[rs(k)];

}inline void mul(int k,int l,int r,int x,int y,int v)

pushdown(k,l,r);

int mid=(l+r)/2;

if(x<=mid)mul(ls(k),l,mid,x,y,v);

if(y>mid)mul(rs(k),mid+1,r,x,y,v);

sum[k]=sum[ls(k)]+sum[rs(k)];

}inline int check(int k,int l,int r,int x,int y)

main(void)

build(1,1,n);

_1for(j,m)

if(cmd==2)

if(cmd==3)

}}

Web前端 從入門到自閉

標籤的快捷鍵 單詞 tab鍵 單詞 h5初始 tab 快速建立符合規範的html doctype html html lang en head meta charset utf 8 title document title head body body html html的注釋 css的注釋 注釋的...

線段樹入門

線段樹 interval tree 是把區間逐次二分得到的一樹狀結構,它反映了包括歸併排序在內的很多分治演算法的問題求解方式。上圖是一棵典型的線段樹,它對區間 1,10 進行分割,直到單個點。這棵樹的特點 是 1.每一層都是區間 a,b 的乙個劃分,記 l b a 2.一共有log2l層 3.給定乙...

線段樹入門

學習下 線段樹的入門級 總結 線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。對於線段樹中的每乙個非葉子節點 a,b 它的左兒子表示的區間為 a,a b 2 右兒子表示的區間為 a b 2 1,b 因此線段樹是平衡二叉樹,最後的子節點數目為...