最普通的樹狀陣列
實現用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項,...