1. 程式人生 > >Query on a tree SPOJ

Query on a tree SPOJ


#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 2e4+100;
int son[maxn], deep[maxn], father[maxn], num[maxn], top[maxn], p[maxn], fp[maxn], pos;
int Treevalue[maxn];

int first[maxn], ntot;

struct Node
{
    int to, next, val;
} edge[maxn];

struct NODE
{
    int a, b, c;
} input[maxn];

void init()
{
    memset(first, -1, sizeof(first));
    memset(son, -1, sizeof(son));
    pos = ntot = 0;
}

void addedge(int s,int t,int val)
{
    edge[ntot].to=t,edge[ntot].val=val;
    edge[ntot].next=first[s],first[s]=ntot++;
}

///樹鏈剖分
void dfs(int x, int pre,  int de)
{
    deep[x] = de;
    father[x] = pre;
    num[x] = 1;
    for(int i = first[x]; i != -1; i = edge[i].next)
    {
        int to = edge[i].to;
        if(to != pre)
        {
            Treevalue[to] = edge[i].val;
            dfs(to, x, de + 1);
            num[x] += num[to];
            if(son[x] == -1 || num[to] > num[son[x]])
                son[x] = to;
        }
    }
    return ;
}

void getlist(int x, int tp)
{
    top[x] = tp;
    p[x] = pos++;
    fp[p[x]] = x;
    if(son[x] != -1)
        getlist(son[x], tp);
    else
        return ;
    for(int i = first[x]; i != -1; i = edge[i].next)
    {
        int to = edge[i].to;
        if(to != father[x] && to != son[x])
            getlist(to, to);
    }
}

struct TreeNode
{
    int l, r, max;
} tree[maxn * 3];

void push_up(int i)
{
    tree[i].max = max(tree[i << 1].max, tree[i << 1 | 1].max);
}

void build(int i,int l,int r)
{
    tree[i].l=l,tree[i].r=r,tree[i].max=0;
    if(l==r)
    {
        tree[i].max=Treevalue[fp[l]];
        return ;
    }
    int mid=(l+r)>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    push_up(i);
}

int Query(int rt,  int L, int R)
{
    if(tree[rt].l >= L && tree[rt].r <= R)
        return tree[rt].max;
    int m = (tree[rt].l + tree[rt].r) >> 1;
    int ans = 0;
    if(L <= m)
        ans = max(ans, Query(rt << 1, L, R));
    if(m < R)
        ans = max(ans, Query(rt << 1 | 1, L, R));
    return ans;
}

void update(int i,int k,int val)//插點
{
    if(tree[i].l == k && tree[i].r == k)
    {
        tree[i].max=val;
        return ;
    }
    int mid=(tree[i].l+tree[i].r)>>1;
    if(k>mid)
        update(i<<1|1,k,val);
    else
        update(i<<1,k,val);
    push_up(i);
}

int getmax(int a, int b)
{
    int res = 0;
    int f1 = top[a], f2 = top[b];
    while(f1 != f2)
    {
        if(deep[f1] < deep[f2])
        {
            swap(f1, f2);
            swap(a, b);
        }
        res = max(res, Query(1, p[f1], p[a]));
        a = father[f1];
        f1 = top[a];
    }
    if(a == b)
        return res;
    if(deep[a] > deep[b])
        swap(a, b);
    return max(res, Query(1, p[son[a]], p[b]));
}

int main()
{
    //freopen("in.txt", "r", stdin);
    int ncase, n;
    cin >> ncase;
    while(ncase--)
    {
        init();
        cin >> n;
        for(int i = 1; i <= n - 1; i++)
        {
            scanf("%d%d%d",&input[i].a,&input[i].b,&input[i].c);
            addedge(input[i].a,input[i].b,input[i].c);
            addedge(input[i].b,input[i].a,input[i].c);
        }
        dfs(1, 0, 0);
        getlist(1,1);
        build(1, 1, n -1 );
        while(1)
        {
            char op[10];
            scanf("%s", op);
            if(op[0] == 'D')
                break;
            if(op[0] == 'C')
            {
                int a, b;
                scanf("%d%d", &a, &b);
                int aa = input[a].a, bb = input[a].b;
                if(deep[aa] < deep[bb])
                    swap(aa, bb);
                update(1, p[aa], b);
            }
            else
            {
                int a, b;
                scanf("%d%d", &a, &b);
                printf("%d\n", getmax(a, b));
            }
        }
    }
    return 0;
}