樹狀陣列小結

2021-09-11 17:40:35 字數 3901 閱讀 1325

最普通的樹狀陣列

實現用low

bi

tlowbit

lowbit

的優秀性質

原理很簡單

#pragma gcc optimize("o3")

#pragma g++ optimize("o3")

#include

#include

#include

#define maxn 500005

#define ll long long

#define reg register ll

#define fo(i,a,b) for (reg i=a;i<=b;++i)

#define fd(i,a,b) for (reg i=a;i>=b;--i)

#define o3 __attribute__((optimize("-o3")))

using

namespace std;

ll a[maxn]

,tr[maxn]

;ll n,m;

o3 inline ll read()

while

('0'

<=ch && ch<=

'9')x=x*

10+ch-

'0',ch=

getchar()

;return x*f;

}o3 inline ll lowbit

(ll x)

o3 inline

void

add(ll x,ll y)

o3 inline ll query

(ll x)

o3 inline ll ask

(ll x,ll y)

o3 int

main()

return0;

}

實現這個的思路比較巧妙

做乙個差分,設b[i

]=a[

i]−a

[i−1

]b[i]=a[i]-a[i-1]

b[i]=a

[i]−

a[i−

1],那麼∑i=

1nb[

i]=a

[i

]\sum^n_b[i]=a[i]

∑i=1n​

b[i]

=a[i

]那麼對於乙個區間的修改[x,

y]

[x,y]

[x,y

]區間加k

kk,相當於x

xx位加k

kk、y+1

y+1y+

1位減k

kk容易知道這是對的,在x

xx前沒有影響,從x

xx開始才有貢獻

用樹狀陣列維護b

bb就好了

#pragma gcc optimize("o3")

#pragma g++ optimize("o3")

#include

#include

#include

#define maxn 500005

#define ll long long

#define reg register ll

#define fo(i,a,b) for (reg i=a;i<=b;++i)

#define fd(i,a,b) for (reg i=a;i>=b;++i)

#define o3 __attribute__((optimize("-o3")))

ll a[maxn]

,tr[maxn]

;ll n,m;

o3 inline ll read()

while

('0'

<=ch && ch<=

'9')x=x*

10+ch-

'0',ch=

getchar()

;return x*f;

}o3 inline ll lowbit

(ll x)

o3 inline

void

change

(ll x,ll y)

o3 inline ll query

(ll x)

o3 int

main()

else

printf

("%lld\n"

,query

(read()

));}

return0;

}

其實這個就是支援區間修改和區間查詢的樹狀陣列

對於一段區間查詢[x,

y]

[x,y]

[x,y

],拆成[1,

x−1]

[1,x-1]

[1,x−1

]和[1,y

][1,y]

[1,y

],單獨考慮[1,

x]

[1,x]

[1,x

]的答案即可

再設乙個c

cc陣列,使c[i

]=b[

i]∗(

i−1)

c[i]=b[i]*(i-1)

c[i]=b

[i]∗

(i−1

)那麼[1,

x]

[1,x]

[1,x

]的和即為x∗q

uery

(b,x

)−qu

ery(

c,x)

x*query(b,x)-query(c,x)

x∗quer

y(b,

x)−q

uery

(c,x

)

#pragma gcc optimize("o3")

#pragma g++ optimize("o3")

#include

#include

#include

#define maxn 500005

#define ll long long

#define reg register ll

#define fo(i,a,b) for (reg i=a;i<=b;++i)

#define fd(i,a,b) for (reg i=a;i>=b;++i)

#define o3 __attribute__((optimize("-o3")))

ll a[maxn]

,tr[maxn]

,tr1[maxn]

;ll n,m;

o3 inline ll read()

while

('0'

<=ch && ch<=

'9')x=x*

10+ch-

'0',ch=

getchar()

;return x*f;

}o3 inline ll lowbit

(ll x)

o3 inline

void

change

(ll *tr,ll x,ll y)

o3 inline ll query

(ll *tr,ll x)

o3 int

main()

else x=

read()

,y=read()

,printf

("%lld\n"

,(y*

query

(tr,y)

-(x-1)

*query

(tr,x-1)

)-(query

(tr1,y)

-query

(tr1,x-1)

));}

return0;

}

樹狀陣列學習小結

樹狀陣列,又稱二進位制索引樹,英文名binary indexed tree。一 樹狀陣列的用途 主要用來求解數列的字首和,a 0 a 1 a n 由此引申出三模擬較常見問題 1 單點更新,區間求值。hdu1166 2 區間更新,單點求值。hdu1556 3 求逆序對。hdu2838 二 樹狀陣列的表...

Book 樹狀陣列 小結

差不多花了10天學樹狀陣列,是照著這篇部落格做的題目,還差幾道 1.幾個注意的地方 1 lowbit 0 0 會無限迴圈,會導致tle掉,給輸入進去的x 一下就好 2 當給的x的範圍很大的時候,注意要離散化 2.然後就是兩個基本的操作 1 add 2 sum 3.複雜度是log n 4.現在做到的題...

樹狀陣列小結(未完待續)

最近剛剛深入到了樹狀陣列是什麼,上年寒假學過,但是當時完全聽不到,最近兩天沉下心來,好好看了下,終於懂這個原理是什麼,感覺並不是很難,而且很好用。這個圖應該更好理解 d 1 a 1 d 2 a 1 a 2 d 3 a 3 d 4 a 1 a 2 a 3 a 4 依次類推,6管著5和6 8管著前8項,...