POJ 3237 Tree 樹鏈剖分

2022-05-22 08:48:12 字數 2464 閱讀 2852

題意:

給出一棵樹,每條邊有乙個權值。下面有3種操作:

分析:因為是線段樹成段取反操作,可以先打個neg標記,表示這段區間的數是否取反。

再維護區間最大值和最小值,取反之後,新區間的最大值是原來最小值的相反數,新區間最小值是原來最大值的相反數。

#include #include #include using namespace std;

const int maxn = 10000 + 10;

const int maxnode = maxn * 4;

struct edge

edge(int v, int nxt): v(v), nxt(nxt) {}

};int n, u[maxn], v[maxn], w[maxn];

int ecnt, head[maxn];

edge edges[maxn * 2];

void addedge(int u, int v)

int tot;

int sz[maxn], fa[maxn], dep[maxn], son[maxn], up[maxn];

int id[maxn], pos[maxn], top[maxn];

void dfs(int u)

}void dfs2(int u, int tp)

}int maxv[maxnode], minv[maxnode], neg[maxnode];

void pushup(int o)

void build(int o, int l, int r)

int m = (l + r) / 2;

build(o<<1, l, m);

build(o<<1|1, m+1, r);

pushup(o);

}void inverse(int& a, int &b)

void pushdown(int o)

}void change(int o, int l, int r, int p, int v)

int m = (l + r) / 2;

pushdown(o);

if(p <= m) change(o<<1, l, m, p, v);

else change(o<<1|1, m+1, r, p, v);

pushup(o);

}void update(int o, int l, int r, int ql, int qr)

int m = (l + r) / 2;

pushdown(o);

if(ql <= m) update(o<<1, l, m, ql, qr);

if(qr > m) update(o<<1|1, m+1, r, ql, qr);

pushup(o);

}void update(int u, int v)

update(1, 1, n, id[t1], id[u]);

u = fa[t1]; t1 = top[u];

} if(u == v) return;

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

update(1, 1, n, id[son[u]], id[v]);

}int qans;

void query(int o, int l, int r, int ql, int qr)

int m = (l + r) / 2;

pushdown(o);

if(ql <= m) query(o<<1, l, m, ql, qr);

if(qr > m) query(o<<1|1, m+1, r, ql, qr);

}void query(int u, int v)

query(1, 1, n, id[t1], id[u]);

u = fa[t1]; t1 = top[u];

} if(u == v) return;

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

query(1, 1, n, id[son[u]], id[v]);

}int main()

dfs(1);

tot = 0;

dfs2(1, 1);

n--;

memset(maxv, 0, sizeof(maxv));

memset(minv, 0, sizeof(minv));

memset(neg, 0, sizeof(neg));

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

if(dep[u[i]] < dep[v[i]])

swap(u[i], v[i]);

build(1, 1, n);

char cmd[10];

int a, b;

while(scanf("%s", cmd) == 1)

} }return 0;

}

poj3237 Tree 樹鏈剖分

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

POJ3237 Tree 樹鏈剖分

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

POJ3237 Tree 樹鏈剖分 邊權

傳送門 n個點的,n 1條邊 修改單邊邊權 將a b的邊權取反 查詢a b邊權最大值 修改邊權就查詢點的深度大的點,用大的點去存這條邊的邊權,其餘的就和點權的是一樣的了 取反操作用線段樹維護,區間最大值取反就是區間最小值,區間最小值取反就是區間最大值 所以維護兩顆線段樹即可,lazy標記表示覆蓋單邊...