HDU snacks (線段樹 dfs序)

2021-08-22 13:48:09 字數 2763 閱讀 5348

problem description

input

輸入資料第一行是乙個整數,表示有組測試資料。

對於每組資料,包含兩個整數,表示有個零食機,次操作。

接下來行,每行兩個整數和,表示編號為的零食機與編號為的零食機相連。

接下來一行由個數組成,表示從編號為0到編號為的零食機的初始價值。

接下來行,有兩種操作:,表示編號為的零食機的價值變為;,表示詢問從編號為0的零食機出發,必須經過編號為零食機的路線中,價值總和的最大值。

本題可能棧溢位,辛苦同學們提交語言選擇c++,並在**的第一行加上:

`#pragma comment(linker, "/stack:1024000000,1024000000") `

output

對於每組資料,首先輸出一行」case #?:」,在問號處應填入當前資料的組數,組數從1開始計算。

對於每次詢問,輸出從編號為0的零食機出發,必須經過編號為零食機的路線中,價值總和的最大值。

sample input

1

6 50 1

1 20 3

3 45 3

7 -5 100 20 -5 -7

1 11 3

0 2 -1

1 11 5

sample output

case #1:

10227

220

首先dfs序,dfs序之後,我們順便把每個點到根節點的距離求出來。

dfs 序之後,我們得到了乙個兩個時間戳,乙個進,乙個出,

這個時間戳和線段樹的區間即為類似,

比如乙個節點,,他的孩子的時間戳一定包含於這個節點的時間戳。

我們的線段樹用進入的時間戳建樹。

然後維護區間最大值,就是當前節點到根節點的價值。。

當我們修改節點的時候,當前節點和節點和孩子的價值都會改變,

所以這就成 了乙個線段樹 修改區間,查詢區間的問題了。

這個題我  wa 了幾個小時,是因為資料時 long long,

而我的inf 是 int 的,進行比較,不能得出來正確答案。

導致一直wa

#pragma comment(linker, "/stack:1024000000,1024000000") 

#include #include #include #include #define mem(x,v) memset(x,v,sizeof(x))

#define rep(i,a,b) for (int i = a; i < b; i++)

#define per(i,a,b) for (int i = a; i > b; i--)

#define low(x) (x & (-x))

using namespace std;

typedef long long ll;

const double eps = 1e-10;

const long long inf = 1e18;

const int n = 1e5+10;

const int m = 1e5+10;

struct nodef[n*2];

struct segg[n*4];

int n,m,t;

int cnt,l[n],r[n],tim,head[n],d[n];

ll dis[n],a[n],val;

void add_edge(int u, int v)

void push_down(int p)

void build(int p, int a, int b)

int m = (a + b) / 2;

t++; g[p].l = t; build(t,a,m);

t++; g[p].r = t; build(t,m,b);

g[p].w = max(g[g[p].l].w,g[g[p].r].w);

return;

}void insert(int p, int x, int y, int z)

push_down(p);

int m = (g[p].a + g[p].b) / 2;

if (x < m) insert(g[p].l, x,y,z);

if (y >= m) insert(g[p].r,x,y,z);

g[p].w = max(g[g[p].l].w, g[g[p].r].w);

return;

}ll qurey(int p, int x, int y)

push_down(p);

int m = (g[p].a + g[p].b) / 2;

if (x < m) ans = max(ans,qurey(g[p].l,x,y));

if (y >= m) ans = max(ans, qurey(g[p].r,x,y));

return ans;

}void dfs(int u, int fa)

r[u] = tim;

return;

}int main()

rep(i,0,n)

tim = 0;

dis[0] = a[0];//是多組資料,每次要注意初始情況,,這樣寫就沒事。

dfs(0,0);

t = 1;

build(1,1,n+1);

printf("case #%d:\n",num++);

int op,x;

rep(i,0,m) else

} }return 0;

}

dfs序 線段樹

傳送門 現有一棵樹,有以下操作 1.節點x及其所有子孫顏色都變更為k。2.要求你回答節點x的顏色。初始所有點都沒有染色。input 第一行乙個整數t t 10 表示樣例組數。對於每個測試樣例 第一行乙個整數n n 5e4 表示樹的節點個數。接下來n行,每行兩個整數u,v 1 u,v n 表示樹中u的...

求和(dfs序 線段樹)

題意 已知有n個節點,有n 1條邊,形成乙個樹的結構。給定乙個根節點k,每個節點都有乙個權值,節點i的權值為vi 給m個操作,操作有兩種型別 1 a x 表示將節點a的權值加上x 2 a 表示求a節點的子樹上所有節點的和 包括a節點本身 題解 dfs序 線段樹 用dfs序確定in x 和out x ...

3252 攻略 dfs序 線段樹

首先維護乙個根到底路徑的字首和,選某個點代表選了此點到根的路徑。那麼每次選擇了乙個點 x 這個點所在子樹內的每個點都要減少vx 的收益,那麼對於子樹的區間減可以用df s i nf,代表不可再次選到。由於每個點只會被刪除一次,而刪除一次的複雜度為o logn 所以總的複雜度為o nlog n inc...