POJ 3237 Tree (樹鏈剖分 線段樹)

2021-06-28 13:51:39 字數 2440 閱讀 7019

題意:在樹上有三種操作。

change a b1.將第a條邊的值賦值為b;

negate a b 2.將a節點到b節點路徑上的邊變為其相反數。

query a b 3.訪問a節點到b節點的路徑上的邊權最大。

ac**:

#include #include #include #define in freopen ("in.txt" , "r" , stdin);

using namespace std;

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

const int maxn=100010+10;

const int inf=100000000;

struct edge;

struct edge edge[maxn*2];

int head[maxn],tot;

int fa[maxn];//f[v] 表示v的父親節點

int son[maxn];//表示 與v同在一重鏈上的兒子節點(重兒子)

int num[maxn];//num[v] v為根的子樹的節點數。

int top[maxn];//top[v] v所在鏈的頂端節點。

int deep[maxn];//deep[v] 表示v的深度(根的深度為1)

int data[maxn];

int pos,n;

void addedge(int u,int v)

void dfs1(int u,int father,int dep)

} }}//給點編號得到線段樹上的對應標號

void getpos(int u,int sp) }}

void init()

//樹狀陣列or線段樹or其他

struct node;

struct node tree[maxn*3];

void pushup(int rt)

void pushdown(int rt)

}void build(int l,int r,int rt)

int m=(tree[rt].l+tree[rt].r)>>1;

build(lson);

build(rson);

pushup(rt);

}void update(int p,int add,int rt)

pushdown(rt);

int m=(tree[rt].l+tree[rt].r)>>1;

if(p<=m) update(p,add,rt<<1);

else update(p,add,rt<<1|1);

pushup(rt);

}void update2(int l,int r,int rt)

pushdown(rt);

int m=(tree[rt].l+tree[rt].r)>>1;

if(l<=m) update2(l,r,rt<<1);

if(r>m) update2(l,r,rt<<1|1);

pushup(rt);

}int query_max(int l,int r,int rt)

pushdown(rt);

int m=(tree[rt].l+tree[rt].r)>>1;

int ret=-inf;

if(l<=m) ret=max(ret,query_max(l,r,rt<<1));

if(r>m) ret=max(ret,query_max(l,r,rt<<1|1));

pushup(rt);

return ret;

}int find_max(int u,int v)

void change(int u,int v)

int e[maxn][5];

int main()

char op[10];

while(1)

} return 0;}/*

1071 2 1

1 3 2

3 4 3

3 5 4

5 6 5

5 7 6

negate 1 3

query 1 4

negate 2 4

change 4 40

query 4 5

negate 2 7

query 2 7

query 3 5

change 4 30

negate 2 7

query 4 7

query 4 5

query 2 7

done106

1 2 1

2 5 2

2 6 3

1 3 4

3 4 5

query 4 5

change 1 3

query 4 5

*/

poj3237 Tree 樹鏈剖分

這個題是spoj的改版 是在原來的題意上增加了區間取反操作 所以只需要在spoj375的基礎上再線段樹上增加乙個取反標誌 同時在維護乙個區間最小值 因為在區間取反了以後 區間的最大值就是區間原來的最小值 嗯 就這樣就可以了 include include include using namespac...

POJ3237 Tree 樹鏈剖分

題意 給定一棵樹,有3種操作,1.修改某條邊,2.給兩個點間路徑上的邊取相反數,3.求兩個點間路徑上的邊權的最大值 思路 樹鏈剖分,求區間最大值,又能取反,那麼線段樹維護乙個最大值和最小值,取反的時候,一段區間的最大值取反 賦給 最小值,最小值取反 賦給 最大值。同時,需要乙個laze標記。incl...

POJ 3237 Tree 樹鏈剖分

題意 給出一棵樹,每條邊有乙個權值。下面有3種操作 分析 因為是線段樹成段取反操作,可以先打個neg標記,表示這段區間的數是否取反。再維護區間最大值和最小值,取反之後,新區間的最大值是原來最小值的相反數,新區間最小值是原來最大值的相反數。include include include using n...