線段樹,樹狀陣列基礎

2021-08-14 17:49:22 字數 2695 閱讀 1624

線段樹操作

樹狀陣列操作

線段樹的操作有:

單點修改,logn

區間修改,logn (加lazy陣列)

單點查詢,logn

區間查詢,logn

樹狀陣列的操作有:

單點修改,logn

區間修改,logn

單點查詢,logn

區間查詢,logn

兩者對比

樹狀陣列和線段樹相比,空間減少大概4倍,時間較快,**量少。但是線段樹便於理解,樹狀陣列很巧妙.

單點修改

//將下標x的值修改為y

void sert(int i,int l,int r,int x,int y)

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

if(x<=mid) sert(i<<1,l,mid,x,y);

else sert(i<<1|1,mid+1,r,x,y);

v[i]=v[i<<1]+v[i<<1|1];

}

區間修改
void upd(int i,int l,int r,int mid)

//將區間[l,r]的值增加x

void change(int i,int l,int r,int l,int r,int x)

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

if(lazy[i]) upd(i,l,r,mid);

if(r<=mid) change(i<<1,l,mid,l,r,x);

else

if(l>mid) change(i<<1|1,mid+1,r,l,r,x);

else

v[i]=v[i<<1]+v[i<<1|1];

}

單點查詢
int query(int i,int l,int r,int x)

區間查詢
void query(int i,int l,int r,int l,int r)

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

if(lazy[i]) upd(i,l,r,mid);//如果沒有區間修改的話,這個可以去掉

if(r<=mid) query(i<<1,l,mid,l,r);

else

if(l>mid) query(i<<1|1,mid+1,r,l,r);

else

}

組合操作

線段樹的單點修改區間查詢,區間修改單點查詢,單點修改單點查詢,區間修改區間查詢就是上面單個操作的組合呀,就是區間修改的時候,可能有時候lazy會打的有點麻煩。

**比較多,一點不要手誤…

單點修改

這裡給的是單點增加乙個值,如果要改單點的值的話,那麼就加上它們的差就行了

//將id位置的值,增加x

void change(int

id,int x)

}

區間查詢

如果要查詢l..r區間的和,sum[r]-sum[l-1]就行了

//查詢區間1...x的和

intsum(int x)

return ans;

}

區間修改

區間修改單點查詢

//往上更新,然後查詢的時候,往下加

//乙個陣列a,開始時候有n個值,然後m個操作,1 x y z表示對將a[x]...a[y]的值都增加z

//2 x 查詢x點的值

int lowbit(int k)

void change(int k,int num)

return;

}int sum(int k)

return ans;

}int main()

int t1,t2,t3,t4;

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

if(t1==2)

區間修改區間查詢

比如要查詢[l,r]的區間和

$sum[i]=a[1]+a[2]+…+a[i]+delta[1]i+delta[2](i-1)+…+delat[i] =∑

a[x]

+(i+

1)∗∑

delt

a[x]

+∑x∗

delt

a[x]

sum[i]:表示從1到i的區間和,delta[i]:表示i到n的增量,那麼就相當於兩個樹狀陣列操作

sum[l…r]=sum[r]-sum[l-1]

using namespace std;

#define ll long long

const int maxn = 2e5+10;

ll sum[maxn],delta[maxn],deltai[maxn];

int n,q,x,l,r;

int lowbit(int

x)void change(ll *a,int i,intx)}

ll query(ll *a,int i)

return ans;

}int main()

scanf("%d",&q);

while(q--)

else

}return

0;}

線段樹,樹狀陣列,主席樹

樹狀陣列 主席樹 包括無修改和可修改。用乙個滿二叉樹 葉子節點可以為空 來維護乙個連續陣列,整個樹的所有葉子節點從左到右表示整個陣列,每個非葉子節點表示其所有葉子的集合所描述的乙個連續子陣列的某一特性 最小值,最大值等 可以在logn的複雜度內實現對任意連續欄位的給定特性的查詢 最小值等 可以在lo...

線段樹 劃分樹 樹狀陣列

線段樹 利用陣列來維護乙個類似字首和的區間和 在查詢的時候查這個區間陣列 特殊操作 有延時標記 在區間陣列上增加基本不改變原來陣列 以達到節省時間的目的 樹狀陣列 和線段樹類似 乙個用乙個陣列維護類似字首和的東西 但 是 它維護的是乙個用二進位制表示的字首和 舉個例子 1是1 2是1 2 3是3 4...

Apple Tree(樹狀陣列 線段樹)

description 3 1 2 1 3 3 q 1 c 2 q 1 sample output 3 2 題目大意 一棵樹上長了蘋果,每乙個樹枝節點上有長蘋果和不長蘋果兩種狀態,兩種操作,一種操作能夠改變樹枝上蘋果的狀態,另一種操作詢問某一樹枝節點一下的所有的蘋果有多少。樹狀陣列版 include...