poj 3237 Tree 樹鏈剖分 線段樹

2021-08-07 11:40:52 字數 2162 閱讀 4852

給定一棵樹,每條邊上都有權值。

三種操作:

1. 修改某條邊的權值

2. 將某條樹鏈上所有邊的權值變為相反數

3. 詢問某條樹鏈上的最大邊權

先樹鏈剖分,然後建線段樹,維護一段的最大值和最小值(la

zyta

g 好題)。

#include 

#include

#include

#include

#define lson (rt << 1)

#define rson (rt << 1 | 1)

#define maxn 100010

#define inf 0x3f3f3f3f

using namespace std;

typedef long long ll;

struct edge

}edge[maxn * 2];

struct node tr[maxn * 4];

struct e

}e[maxn];

int fa[maxn], dep[maxn], ne[maxn], son[maxn], sz[maxn], val[maxn], top[maxn], le[maxn], tot, cnt, p[maxn], w[maxn];

void add(int u, int v, int w)

void dfs1(int u, int f, int d)

}void dfs2(int u, int sp)

} int temp = mx;

mx = -mn;

mn = -temp;

}void push_up(int rt)

void push_down(int rt)

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

int mid = l + r >> 1;

build(lson, l, mid); build(rson, mid + 1, r);

push_up(rt);

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

push_down(rt);

int mid = tr[rt].l + tr[rt].r >> 1;

if (r <= mid) modify1(lson, l, r);

else

if (l > mid) modify1(rson, l, r);

else

push_up(rt);

}void modify2(int rt, int

x, int w)

push_down(rt);

int mid = tr[rt].l + tr[rt].r >> 1;

if (x

<= mid) modify2(lson, x, w);

else modify2(rson, x, w);

push_up(rt);

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

int ask(int u, int v)

if (u == v) return ans;

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

ans = max(ans, query(1, le[v]+1, le[u]));

return ans;

}void change(int u, int v)

if (u == v) return;

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

modify1(1, le[v]+1, le[u]);

}void work()

dfs1(1, -1, 0); dfs2(1, 1);

for (int i = 1; i <= n; ++i) w[le[i]] = val[i];

for (int i = 1; i < n; ++i) p[i] = dep[e[i].u] > dep[e[i].v] ? e[i].u : e[i].v;

build(1, 1, n);

char s[10];

while (scanf("%s", s) && s[0] != 'd')

}int main()

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...