2017暑假訓練第九天

2021-08-05 22:05:19 字數 1409 閱讀 3591

上午剛剛看完了樹狀陣列的知識點,就自己的理解先做一下總結,整理一下學到了什麼。

樹狀陣列:

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 位置很好描述,但是形狀太複雜了,我們怎麼...