Spoj375 Query on a tree 裸·树链剖分

来源:互联网 发布:湖南自兴人工智能学院 编辑:程序博客网 时间:2024/05/23 13:34

题意:
边修改,树上最值查询
分析:
又裸又水,略
代码:

#include<bits/stdc++.h>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 100000 + 10;void read(int &n) {    int f = 1; n = 0;    char ch = getchar();    while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); }    while(ch >='0' && ch <='9') { n = n * 10 + ch - 48; ch = getchar(); }    n *= f;}struct SegmentTree {    int Max[maxn * 4];    void init() { memset(Max, 0, sizeof(Max)); }    void Push_up(int u) {        int lc = u << 1, rc = u << 1 | 1;        Max[u] = max(Max[lc], Max[rc]);    }    void update(int u, int l, int r, int sl, int sr, int v) {        if(sl <= l && r <= sr) { Max[u] = v; return; }        int mid = (l + r) >> 1, lc = u << 1, rc = u << 1 | 1;        if(sl <= mid) update(lc, l, mid, sl, sr, v);        if(sr > mid) update(rc, mid+1, r, sl, sr, v);        Push_up(u);    }    int query(int u, int l, int r, int sl, int sr) {        if(sl <= l && r <= sr) return Max[u];        int Tmp = -INF;        int mid = (l + r) >> 1, lc = u << 1, rc = u << 1 | 1;        if(sl <= mid) Tmp = max(Tmp, query(lc, l, mid, sl, sr));        if(sr > mid) Tmp = max(Tmp, query(rc, mid+1, r, sl, sr));        return Tmp;    }}ST;struct Edge {    int from, to, dist;}e[maxn];int Begin[maxn], Next[maxn*2], To[maxn*2], E;void Add(int x, int y) {    To[++E] = y;    Next[E] = Begin[x];    Begin[x] = E;}int cnt, n;int tid[maxn], son[maxn], top[maxn], fa[maxn], size[maxn], dep[maxn];void dfs(int cur, int f, int d) {    dep[cur] = d;    size[cur] = 1;    for(int i=Begin[cur]; i; i=Next[i]) {        int t = To[i];        if(t != f) {            dfs(t, cur, d+1);            fa[t] = cur;            size[cur] += size[t];            if(son[cur] == -1 || size[t] > size[son[cur]])                son[cur] = t;        }    }}void dfs(int cur, int tp) {    top[cur] = tp;    tid[cur] = ++cnt;    if(son[cur] == -1) return;    dfs(son[cur], tp);    for(int i=Begin[cur]; i; i=Next[i]) {        int t = To[i];        if(t != fa[cur] && t != son[cur])             dfs(t, t);    }}void init() {    E = cnt = 0;    ST.init();    memset(fa, 0, sizeof(fa));     memset(son, -1, sizeof(son));    memset(Begin, 0, sizeof(Begin));    for(int i=1; i<n; i++) {        scanf("%d%d%d", &e[i].from, &e[i].to, &e[i].dist);        Add(e[i].from, e[i].to); Add(e[i].to, e[i].from);    }    dfs(1, 1, 1); dfs(1, 1);    for(int i=1; i<n; i++) {        if(dep[e[i].to] < dep[e[i].from]) swap(e[i].to, e[i].from);        ST.update(1, 2, cnt, tid[e[i].to], tid[e[i].to], e[i].dist);    }}int Getmax(int x, int y) {    int ans = -INF;    while(top[x] != top[y]) {        if(dep[top[x]] < dep[top[y]]) swap(x, y);        ans = max(ans, ST.query(1, 2, cnt, tid[top[x]], tid[x]));        x = fa[top[x]];    }    if(dep[x] > dep[y]) swap(x, y);    if(x != y) ans = max(ans, ST.query(1, 2, cnt, tid[x]+1, tid[y]));    return ans;}char s[20];int T, u, v;int main() {#ifndef ONLINE_JUDGE    freopen("data.txt", "r", stdin);    freopen("ans.txt", "w", stdout);#endif    read(T);    while(T--) {        read(n); init();        while(scanf("%s", s) == 1 && s[0] != 'D') {            read(u), read(v);            if(s[0] == 'C')                 ST.update(1, 2, cnt, tid[e[u].to], tid[e[u].to], v);            else                 printf("%d\n", Getmax(u, v));        }    }    return 0;}
0 0
原创粉丝点击