spoj 375

樹鏈剖分  此題是修改邊的權值 

樹鏈剖分部分 參考http://blog.sina.com.cn/s/blog_7a1746820100wp67.html

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <stack>
#include <vector>
#include <sstream>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <algorithm>
#include <iostream>
#define FFI freopen("in.txt", "r", stdin)
#define maxn 20010
#define INF 0x3f3f3f3f
#define inf 10000000
#define MOD 1000000007
#define ULL unsigned long long
#define LL long long
#define _setm(houge) memset(houge, INF, sizeof(houge))
#define _setf(houge) memset(houge, -1, sizeof(houge))
#define _clear(houge) memset(houge, 0, sizeof(houge))
using namespace std;

struct node
{
    int l;
    int r;
    int max_val;
    int setv;
};
node a[maxn<<2], p;
void pushup(int rt)
{
    a[rt].max_val = max(a[rt<<1].max_val, a[rt<<1|1].max_val);
}
void pushdown(int rt)
{
    if(a[rt].setv != -1)
    {
        a[rt<<1].setv = a[rt<<1|1].setv = a[rt].setv;
        a[rt<<1].max_val = a[rt<<1|1].max_val = a[rt].setv;
        a[rt].setv = -1;
    }
}
void build(int l, int r, int rt)
{
    a[rt].max_val = 0;
    a[rt].setv = -1;
    a[rt].l = l;
    a[rt].r = r;
    if(l == r)
        return;
    int m = (l + r) >> 1;
    build(l, m, rt<<1);
    build(m+1, r, rt<<1|1);
}

void update(int x, int y, int rt, int v)
{
    if(a[rt].l == x && a[rt].r == y)
    {
        a[rt].setv = v;
        a[rt].max_val = v;
        return;
    }
    pushdown(rt);
    int m = (a[rt].l + a[rt].r) >> 1;
    if(y <= m)
        update(x, y, rt<<1, v);
    else if(x > m)
        update(x, y, rt<<1|1, v);
    else
    {
        update(x, m, rt<<1, v);
        update(m+1, y, rt<<1|1, v);
    }
    pushup(rt);
}

void query(int x, int y, int rt)
{
    if(a[rt].l == x && a[rt].r == y) {
        p.max_val = max(p.max_val, a[rt].max_val);
        return;
    }
    pushdown(rt);
    int m = (a[rt].l + a[rt].r) >> 1;
    if(y <= m)
        query(x, y, rt<<1);
    else if(x > m)
        query(x, y, rt<<1|1);
    else {
        query(x, m, rt<<1);
        query(m+1, y, rt<<1|1);
    }
    pushup(rt);
}

struct Tedge
{ int b, next; } e[maxn * 2];
int n, z, edge, root;
int d[maxn][3];
int first[maxn], dep[maxn], w[maxn], fa[maxn], top[maxn], son[maxn], siz[maxn];

void insert(int a, int b) {
    e[++ edge].b = b;
    e[edge].next = first[a];
    first[a] = edge;
}

void dfs(int v) {
    siz[v] = 1, son[v] = 0;
    for(int i = first[v]; i > 0; i = e[i].next) {
        if(e[i].b != fa[v]) {
            fa[e[i].b] = v;
            dep[e[i].b] = dep[v]+1;
            dfs(e[i].b);
            if(siz[e[i].b] > siz[son[v]]) son[v] = e[i].b;
            siz[v] += siz[e[i].b];
        }
    }
}

void build_tree(int v, int tp) {
    w[v] = ++ z, top[v] = tp;
    if(son[v] != 0) build_tree(son[v], tp);
    for(int i = first[v]; i > 0; i = e[i].next) {
        if(e[i].b != fa[v] && e[i].b != son[v])
            build_tree(e[i].b, e[i].b);
    }
}

int _find(int va, int vb)
{
    int f1 = top[va], f2 = top[vb], tmp = 0;
    while (f1 != f2) {
        if(dep[f1] < dep[f2]) {
            swap(f1, f2);
            swap(va, vb);
        }
        p.max_val = 0;
        query(w[f1], w[va], 1);
        tmp = max(tmp, p.max_val);
        va = fa[f1];
        f1 = top[va];
     }
     if(va == vb) return tmp;
     if(dep[va] > dep[vb]) swap(va, vb);
     p.max_val = 0;
     query(w[son[va]], w[vb], 1);
     return max(tmp, p.max_val);
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t --) {
        scanf("%d", &n);
        root = (n+1)/2;
        fa[root] = z = dep[root] = edge = 0;
        _clear(siz);
        _clear(first);
        for(int i = 1; i < n; ++ i) {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            d[i][0] = a, d[i][1] = b, d[i][2] = c;
            insert(a, b);
            insert(b, a);
        }
        dfs(root);
        build_tree(root, root);
        //puts("121");
        build(1, z, 1);
        for(int i = 1; i < n; ++ i) {
            if (dep[d[i][0]] > dep[d[i][1]]) swap(d[i][0], d[i][1]);
            update(w[d[i][1]], w[d[i][1]], 1, d[i][2]);
        }
        char s[10];
        while(scanf("%s", s) == 1 && s[0] != 'D') {
            int a, b;
            scanf("%d%d", &a, &b);
            if(s[0] == 'Q') {
                printf("%d\n", _find(a, b));
            }
            else {
                update(w[d[a][1]], w[d[a][1]], 1, b);
            }
        }
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章