Poj3237 樹刨 線段樹 邊權轉點權

2021-09-26 09:43:45 字數 2773 閱讀 5936

題意:在樹上操作,每次將兩點路徑值全變負和單點修改。每次求兩點間路徑的最大值。

思路:邊權轉點權的話,每次把一條邊的兒子點作為該邊的權值。想起來挺好想,很容易出問題。

查詢修改的話,要將多算的那條lca去掉就可以了。剩下的就是板子。

總結:去掉lca,只需要判斷top[x]==top[y]時,x和y是否相等,不等把deep淺的點+1即可。

邊權轉點權,因為你不知道誰是誰的父親,所以要樹刨完或者第一遍dfs完建點權和樹,單點修改也是。

**:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

#define ll long long

#define forn(i,n) for(int i=0;i#define for1(i,n) for(int i=1;i<=n;i++)

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

const

int maxn =

1e4+5;

const

int inf =

0x3f3f3f3f

;int a[maxn]

,top[maxn]

,p[maxn]

,sz[maxn]

,par[maxn]

,son[maxn]

,deep[maxn]

,fp[maxn]

,id,now;

pairint,

int>

,int

>g[maxn]

;vector<

int>e[maxn]

;class

segment_tree

}node[maxn<<2]

;void

pushup

(int now)

void

pushdown

(int now)

}void

maketree

(int l,

int r,

int now =1)

;if(l==r)

maketree

(l,l+r>>

1,now<<1)

;maketree

((l+r>>1)

+1,r,now<<1|

1);pushup

(now);}

void

update

(int pos,

int v,

int now =1)

pushdown

(now);if

(pos<=ndl.r)

update

(pos,v,now<<1)

;else

update

(pos,v,now<<1|

1);pushup

(now);}

void

update2

(int l,

int r,

int now =1)

pushdown

(now);if

(l<=ndl.r)

update2

(l,r,now<<1)

;if(r>=ndr.l)

update2

(l,r,now<<1|

1);pushup

(now);}

intquery

(int l,

int r,

int now =1)

}tree;

void

dfs(

int u,

int pre,

int d)

}void

getpos

(int u,

int gg)

}void

init()

}intq(

int x,

int y)

if(x!=y)

return res;

}void

change

(int x,

int y)

if(x!=y)

}int

main()

,z};

e[x]

.push_back

(y);

e[y]

.push_back

(x);

}dfs(1

,0,0

);getpos(1

,0);

for1

(i,n-1)

tree.

maketree(1

,n);

string s;

while

(cin>>s)

}return0;

}/*36

1 2 2

1 3 1

3 4 3

3 5 4

5 6 5

q 4 5

q 1 3

n 4 5

q 4 5

q 5 4

q 1 3

c 4 1

q 4 5

q 5 4

q 1 3

d*/

Poj3237 樹刨 線段樹 邊權轉點權

題意 在樹上操作,每次將兩點路徑值全變負和單點修改。每次求兩點間路徑的最大值。思路 邊權轉點權的話,每次把一條邊的兒子點作為該邊的權值。想起來挺好想,很容易出問題。查詢修改的話,要將多算的那條lca去掉就可以了。剩下的就是板子。總結 去掉lca,只需要判斷top x top y 時,x和y是否相等,...

樹鏈剖分 線段樹 POJ3237 權值在邊 模板

include include include include include include include include includeusing namespace std const int maxn 100010 struct edgeedge maxn 2 int head maxn ...

poj 3237 樹鏈剖分 線段樹

題意 給一棵樹,三種操作。將第i條邊的權值改為v,將a到b的路徑上的邊的權值全部取反,求a到b路徑上邊的權值的最大值。思路 明顯的樹鏈剖分,加上線段樹的操作。因為有取反的操作所以每個區間要記錄最大值和最小值。查詢兩點間的路徑時,用求公共祖先的方式去求。include include includec...