樹狀陣列維護子樹和

2022-06-01 01:00:17 字數 1049 閱讀 4551

題目鏈結

problem

\(已知有 n 個節點,有 n−1 條邊,形成乙個樹的結構\)。

\(給定乙個根節點 k,每個節點都有乙個權值,節點i的權值為 vi\)

\(給 m 個操作,操作有兩種型別:\)

\(1\space a\space x :表示將節點 a 的權值加上 x\)

\(2\space a :表示求 a 節點的子樹上所有節點的和(包括 a 節點本身)\)

solution

\(有這樣乙個結論:某節點和其所有子樹結點的時間戳dfn是連續的\)

\(我們用乙個dfn時間戳,在進入時為 time1,遍歷完所有子樹結點之後為 time2\)

\(那麼該節點與其所有子樹結點的範圍為乙個連續的time1-time2,這個時候再用樹狀陣列維護即可\)

\(即通過dfn時間戳(dfs序),將樹形轉化為連續線形段\)

#include#define ios ios::sync_with_stdio(0); cin.tie(0);

using namespace std;

typedef long long ll;

const int maxn = 1e6+10;

ll val[maxn];

ll valu[maxn];

vectore[maxn];

int dfn[maxn],ed[maxn];

int cnt;

int n,m,k;

int lowbit(int x)

void add(int x,ll w)

}ll query(int x)

return res;

}void dfs(int p,int fa)

}ed[p] = cnt-1;

}int main()

cnt = 1;

dfs(k,0);

for(int i=1;i<=m;i++)else

}return 0;

}

板子 樹狀陣列

已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數數加上x 2.求出某區間數值和 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含2或4個整數,表示乙個操作,具體如下 操作1 格式 1 ...

樹狀陣列維護區間最值

題目描述 給你乙個1 n的排列和乙個棧,入棧順序給定 你要在不打亂入棧順序的情況下,對陣列進行從大到小排序 當無法完全排序時,請輸出字典序最大的出棧序列 輸入描述 第一行乙個數n 第二行n個數,表示入棧的順序,用空格隔開,結尾無空格 輸出描述 輸出一行n個數表示答案,用空格隔開,結尾無空格 示例1輸...

樹狀陣列維護區間和和區間修改

可以用樹狀陣列在 n logn 內,雖然線段樹也能,但是樹狀陣列的 空間都要比它優越得多.首先我們可以用差分的方法使區間修改可以在log的複雜度完成,但重點在於區間和的查詢.我們知道,此時num i a 1 a 2 a i 可以利用樹狀陣列快速求出.而區間和則是 a 1 a 2 a i a 1 a ...