上午剛剛看完了樹狀陣列的知識點,就自己的理解先做一下總結,整理一下學到了什麼。
樹狀陣列:
1.樹狀陣列的作用--使用背景:
當要同時存在下述兩種運算元次的時候:
1)對第x位置處的資料進行除了刪除,乘除,之外的修改(比如增加或減去乙個數)
2)求某一位置的字首和。
處理以上兩種情況的時候,使用簡單的陣列就不在適用了。(簡單陣列指的是a直接存某一位置的數是多少的陣列以及sum存某個位置字首和的陣列)
2.處理方法:
建立樹狀陣列。
3.引入概念:
與(&):int lowbit(int i)
這個lowbit函式所得到的數是樹狀陣列c和a以及sum之間的重要橋梁。
4.具體關係:
1)樹狀陣列元素c[i]=a[i-lowbit(i)+1]+.......a[i]。
2)陣列a[i]存在於c[i],c[i=i+lowbit(i)],c[i+lowbit(i)].....中。
3)陣列sum[i]=c[i]+c[i-lowbit(i)]+.....。
5.可推廣性,對於多維的陣列,只需每一維都執行如上操作即可。
剛剛又看完了線段樹的知識點,結合上述樹狀陣列的知識點做一下簡單的總結。
線段樹:
1.線段樹的作用--使用背景:
當同時存在如下兩種運算元次的時候:
1)對區間的最大值或者區間和進行查詢或者修改。
2)對點的值進行查詢和修改時。
處理以上兩種情況,區間問題會讓時間複雜度變得極為複雜。
2.處理方法:
建立線段樹。
3.具體關係:
線段樹是把原存點的陣列a處理成樹狀關係,以結構體陣列的方式再行儲存。
4.線段樹的具體使用:
樹的建立**如下:
void build(int id,int l,int r){
tree[id].left=l;
tree[id].right=r;
if (l==r){
tree[id].sum=a[r];
tree[id].max=a[r];
else {
int mid=(l+r)/2;
build (2*id,l,mid);
build (2*id+1,mid+1,r);
tree[id].sum=tree[2*id].sum+tree[2*id+1].sum;
tree[id].max=max(tree[2*id].max,tree[2*id+1].max);
注意到編號為i的樹結點的sum和max僅僅和他的孩子i*2以及i*2+1這兩個子節點有關係,樹的更新和查詢操作也正是利用了這點。
5.總結:
線段樹適用於區間操作,而樹狀陣列適用於字首和操作,二者各有優劣,樹狀陣列空間較小,但處理範圍同樣也小,線段樹恰恰相反
集訓第九天
今天就看了乙個迪傑斯特拉演算法,他的方法就是從乙個頂點出發,找出這個到與它相關頂點的所有路徑,然後在找出其中最小的,作為基量,一次類推 如下 include define inf 0x7fffffff define maxn 50 int matrix maxn maxn void dijkstra...
開課第九天
畫布 1今天是開課第九天,上午講了關於方法的題,下午講了新知識,嗯,今天有點熱,下面就是本寶寶今天的收穫 1 過載 方法名相同,引數列表不同叫做過載,和返回值型別無關。過載方法名必須一致,引數列表不同,和返回值型別無關。引數列表不同 個數不同,順序不同,型別不同 方法過載的時候編譯器會自動找到最適合...
學習第九天
怎麼沒有題面?我怎麼知道?換個鏈結吧!向洛谷勢力低頭 我們畫一下這個小螞蟻走出來的圖形,我們就會發現,是乙個類似長城的形狀 這個題,求最大值,我們應該能很容易想到用動態規劃 那麼對於乙個路徑圍成的圖形,我們需要描述的是它的位置和形狀,所以這顯然是個高維的dp 位置很好描述,但是形狀太複雜了,我們怎麼...