HYSBZ 1036樹鏈剖分

2021-09-12 10:22:20 字數 3365 閱讀 7057

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成

一些操作: i. change u t : 把結點u的權值改為t ii. qmax u v: 詢問從點u到點v的路徑上的節點的最大權值 i

ii. qsum u v: 詢問從點u到點v的路徑上的節點的權值和 注意:從點u到點v的路徑上的節點包括u和v本身

input

輸入的第一行為乙個整數n,表示節點的個數。接下來n – 1行,每行2個整數a和b,表示節點a和節點b之間有

一條邊相連。接下來n行,每行乙個整數,第i行的整數wi表示節點i的權值。接下來1行,為乙個整數q,表示操作

的總數。接下來q行,每行乙個操作,以「change u t」或者「qmax u v」或者「qsum u v」的形式給出。 

對於100%的資料,保證1<=n<=30000,0<=q<=200000;中途操作中保證每個節點的權值w在-30000到30000之間。

output

對於每個「qmax」或者「qsum」的操作,每行輸出乙個整數表示要求輸出的結果。

sample input

4 1 2

2 34 1

4 2 1 3

12qmax 3 4

qmax 3 3

qmax 3 2

qmax 2 3

qsum 3 4

qsum 2 1

change 1 5

qmax 3 4

change 3 6

qmax 3 4

qmax 2 4

qsum 3 4

sample output4 1 2

210 65

6 5

16hint

樹鏈剖分+線段樹模板題:

1

//樹鏈剖分+線段樹 2/*

3i. change u t : 把結點u的權值改為t

4ii. qmax u v: 詢問從點u到點v的路徑上的節點的最大權值 i

5iii. qsum u v: 詢問從點u到點v的路徑上的節點的權值和 (包括u和v本身)6*/

7 #include8

using

namespace

std;

9#define mem(a,b) memset(a,b,sizeof a)

10#define mp make_pair

11#define eps 1e-8

12#define lson l,mid,rt<<1

13#define rson mid+1,r,rt<<1|1

14 typedef long

long

ll;15 typedef unsigned long

long

ull;

16const

int inf=0x3f3f3f3f;17

const ll inf=0x3f3f3f3f3f3f3f3fll;

18const

int maxn=2e5+10;19

intsiz[maxn],top[maxn],fa[maxn],dep[maxn];

20int

tid[maxn],rnk[maxn],son[maxn],cnt;

21int

head[maxn],tot,a[maxn];

2223

struct

node edge[maxn];

2627

struct

tree tree[maxn<<2

];31

32void

init()

3338

3940

void pushup(int

pos)

4145

46void build(int l,int r,int

rt)47

54int mid=(l+r)>>1;55

build(lson); build(rson);

56pushup(rt);57}

5859

void update(int pos,int c,int l,int r,int

rt)60

66int mid=(l+r)>>1;67

if(pos<=mid) update(pos,c,lson);

68else

update(pos,c,rson);

69pushup(rt);70}

7172

int query_sum(int l,int r,int l,int r,int rt)//

求l~r的和

7381

82int query_max(int l,int r,int l,int r,int rt)//

尋找l~r的最大值

8391

92void addedge(int u,int

v)93

9899

void dfs1(int u,int father,int

depth)

100

113}

114}

115116

void dfs2(int u,int

t)117

127}

128129

int lca(int u,int v,int flag)//

沿著樹鏈求lca(根據flag的不同,求不同的值)

130141

if(dep[u]>dep[v]) swap(u,v);

142if(flag) res=max(res,query_max(tid[u],tid[v],1,cnt,1

));143

else res+=query_sum(tid[u],tid[v],1,cnt,1

);144

return

res;

145}

146147

intmain()

148160

for(int i=1;i<=n;i++) scanf("

%d",&a[i]);

161 dfs1(1,0,0

);162 dfs2(1,1

);163 build(1,cnt,1

);164 scanf("

%d",&t);

165while(t--)

166173

}174

return0;

175}

176

view code

posted @

2018-09-26 00:11

songhl 閱讀(

...)

編輯收藏

HYSBZ 1036 樹的統計Count

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成 一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 i ii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 ...

HYSBZ 1036 樹的統計Count

題意 有一棵樹,每個節點有權值。我們現在有三個操作 1 改變某點的權值。2 給出兩個點,求這兩個點之間的路徑上所有點的權值之和。3 給出兩個點,求這兩個點之間的路徑上所有點的最大權值。乙個裸的樹剖,刷了兩三天樹剖的題了,感覺現在已經把樹剖理解的差不多了,具體操作現在已經可以很快在腦海中模擬出來了。i...

HYSBZ 2243 染色 樹鏈剖分

思路 單點的樹鏈剖分題目.大致的思路與邊問題的樹鏈剖分大同小異.只是在處理相鄰的顏色的計算的時候需要仔細.wa了幾發.這邊就寫一下我處理的思路以及記得起來的wa點.理解樹鏈剖分之後,你會明白,樹鏈剖分是按照路徑兩邊往中間縮.所以我用cu,cv標記兩端的顏色.當需要從u開始搜的時候,我就比對一下該端的...