本篇參考 【顧z】dalao的講解。
現講一下差分陣列的定義吧。
a[i]=σn
j=1 b[j]。
幾個栗子:
原陣列1,3,5,2,4。
差分陣列1,2,2,-3,2。
那麼這個陣列有什麼優勢呢?
如果我們要在原陣列中修改一段區間的值,假如是給l到r這段區間加上x,那麼它在差分陣列中的體現就是:b[l]+x,b[r+1]-x。
也就是說:我們把區間修改變成了單點修改。
例題:at2442(洛谷上直接搜就好),洛谷p3948,p3943。其中p3943的題解戳這裡。(難度由低到高排序,在這裡再次感謝顧z dalao)
樹上差分這個東西一般被用來解決樹上的路徑計數問題。
那麼當我們要修改7到8這一條鏈上的值,給它每個點加上1,我們應該怎麼做呢?
對於一顆樹(描紅的點是要加的):
cnt[u]表示給根到u結點的路徑經過的所有點都加上cnt[u]。
我們只需要在差分陣列的7號點加1,8號點加1,他們的lca 4號點-1,lca的父親2號點-1,就行了。
為什麼呢?
cnt[7]+1:我們把1,2,4,7四個節點加上了1。
cnt[8]+1:我們把1,2,4,6,8五個節點加上了1。
注意到此時由根(1)到lca的父親(2)的路徑上所有點都多加了兩遍1,而lca被多加了一次,所以:
cnt[4]-1:我們把1,2,4三個點都減了1。
cnt[2]-1:我們把1,2這兩點減了1。
對於查詢,在dfs時把以它為根的子樹中差分陣列的值都累加起來就是它當前的值了(就相當於是把差分陣列搬到樹上了嘛)。
得出,點差分:
cnt[u]++ cnt[v]++
cnt[lca]-- cnt[father[lca]]--
procedure類似的,我們要給u到v這一條鏈上所有邊都加1,也是差不多的。getans(u,father:longint);
vari,v:longint;
begin
g[u]:=cnt[u];
i:=head[u];
while i<>0
dobegin
v:=vet[i];
if v<>father then
begin
getans(v,u);
g[u]:=g[u]+g[v];
end;
i:=next[i];
end;
if g[u]>ans then ans:=g[u];
end;
begin
for i:=1
to m do
begin
read(x,y);
z:=lca(x,y);
inc(cnt[x]); inc(cnt[y]);
dec(cnt[z]); dec(cnt[f[z,
0]]);
end; getans(1,0); //答案統計再g陣列裡。
end.
還是那張圖(描紅的邊是要加的):
我們把邊壓到點裡(壓到下面的那個點)。
我們只需要在差分陣列的7號點加1,8號點加1,他們的lca 4號點-2就行了。
為什麼呢?
cnt[7]+1:我們把1到2,2到4,4到7這三條邊都加1。
cnt[8]+1:我們把1到2,2到4,4到6,6到8這四條都加1。
注意到此時根(1)到它們的lca(4)的路徑上所有的邊都被多加了2次,所以:
cnt[4]-2:我們把1到2,2到4這兩條邊都減2。
得出邊差分:
cnt[u]++ cnt[v]++
cnt[lca]-2
很簡單,不是嗎?
procedure例題:洛谷p3128,p3258,p2680。其中p2680的題解戳這裡。(難度按由低到高排序,再次感謝顧z dalao——我保證這是最後一次了【滑稽】)getans(u,father:longint);
vari,v:longint;
begin
g[u]:=cnt[u];
i:=head[u];
while i<>0
dobegin
v:=vet[i];
if v<>father then
begin
getans(v,u);
g[u]:=g[u]+g[v];
if (g[v]=num)and(dist[i]>=k) then flag:=true;
end;
i:=next[i];
end;end
;begin
for i:=1
to m do
begin
read(u[i],v[i]);
grand[i]:=lca(u[i],v[i]);
len[i]:=d[u[i]]+d[v[i]]-2*d[grand[i]];
if len[i]>max then max:=len[i];
end;
getans(
1,0); //答案存再g陣列裡。
end;
差分學習筆記
題面傳送門 首先明確,這是一道差分裸題,不要被它的藍標籤嚇到。演算法簡介 差分是一種和字首和類似的資料結構,畢竟在差分過程中要進行字首和,所以字首和是差分的基礎。差分能做到 o 1 修改,但要 o n 查詢,適用範圍不如字首和。差分適合查詢極少,修改大大多於查詢的題目。演算法實現 首先我們定義差分陣...
差分約束學習筆記
以 luogu p5960 為例。n 個未知數,m 組形如 x i x j le y k 的不等式,求可行解。對於每乙個 x i 我們都能找到 a 組關於它的不等式,第 j 形如為 x i x le y therefore x i le min x y x y x y 該不等式取等時 x i min...
12 20 差分約束學習筆記
先來看一組不等式 x1 x2 0 x1 x5 1 x2 x5 1 x3 x1 5 x4 x1 4 x4 x3 1 x5 x3 3 x5 x4 3 在不等式組 1 中,每個不等式都是兩個未知數的差小於等於某個常數 大於等於也可以,因 為左右乘以 1 就可以化成小於等於 這樣的不等式組就稱作 差分約束系...