字首和與差分

2021-08-06 04:22:56 字數 1224 閱讀 5446

數列的字首和: 

sum[i]表示a[1]~a[i]的和 

用處1:求i~j的和sum[j]-sum[i-1] 

用處2:區間修改。設定乙個change陣列。當區間[i,j]上要加k時,我們令change[i]+=k,令change[j+1]-=k。如果我們對change陣列求字首和的話,字首和sum_change[i]就是i這個位置變動的值

樹的字首和有兩種 

– 根路徑字首和sum2[i],指i到根節點所有節點的權值之和。 

– 子樹字首和sum1[i],指i的子樹(包括i本身)所有節點的權值之和。

樹的字首和用處 

–根路徑字首和,可以用來求路徑節點權值和(配合lca食用) 

–假如要求x到y路徑的權值和,x,y的lca是z。則可以用sum[x]+sum[y]-2sum[z]+value[z] 

–子樹字首和,可以用來做路徑修改(也得配合lca食用) 

–設定乙個修改陣列change。如果要對x到y路徑上的所有點權值+k,lca為z。那麼change[x]+=k,change[y]+=k,change[z]-=k,change[fa[z]]-=k。這樣如果最後對change[i]求字首和的話,最後得到的結果就是i權值的修改量 

–特點:可以o(1)修改,但是只能一次查詢(因為要求字首和o(n))

字首和的使用不都是用來差分的? 

二維陣列的差分:ans=sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1] 

二維陣列的修改:用陣列c存修改資訊。在c[x1][y1]處加上a,在c[x2+1][y1]和c[x1][y2+1]處減a,在c[x2+1][y2+1]再加上a。 

最後(i,k)位置上變化的數值就是c陣列在(i,k)位置的字首和。 

基本就是 

樹上差分經典思路 

①利用dfs序的時間戳,乙個點拆成兩個點,每次在in+1,在out-1,然後bit統計字首和,資瓷動態修改和查詢子樹訪問次數。用於子樹打標記。 

②對於點x,y設r=lca(x,y)。在x+1,y+1,r-2,然後從所有葉節點往上累加。用於樹鏈打標記,資瓷查詢某條邊的訪問次數。 

③對於點x,y設r=lca(x,y)。在x+1,y+1,r-1,father[r]-1,然後從所有葉節點往上累加。用於樹鏈打標記,資瓷查詢某個點的訪問次數。

字首和與差分

從陣列第乙個開始累加 s i s i 1 a i 求區間 l,r 的和,o 1 複雜度sum s r s l 1 遞推s i j s i j s i 1 j s i j 1 s i 1 j 1 例題 雷射炸彈一種新型的雷射炸彈,可以摧毀乙個邊長為r的正方形內的所有的目標。現在地圖上有n n 1000...

字首和與差分

例題入口 include const int n 320 int a n n a i 1 a i 0 1.對a 求出平方數 將其值置為1 不是平方數就是0 2.對a求乙個字首和 3.對 a,b 求乙個部分和 int sum n n void init for int i 1 i 100000 i i...

字首和與差分

include using namespace std const int n 1010 int a n n sum n n intmain int x1,y1,x2,y2 while q return0 差分就是資料間的差。是原始陣列的相鄰元素之間的差值,有b i a i 1 a i includ...