Cod sursa(job #1409720)

Utilizator ArhivaArhiva Infoarena Arhiva Data 30 martie 2015 18:02:44
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.17 kb
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int NMAX = 100004;
struct SegmentTree
{
    vector < int >aint;
    vector < int >value;
    int n;
    SegmentTree()
    {
        aint.clear();
        n = 0;
    }
    SegmentTree(const vector < int > _value)
    {
        n = _value.size();
        value.resize(n+1);
        for(int i=1;i<=n;++i)
            value[i] = _value[i-1];
        aint.resize(4*n);
        Build(1,1,n);
    }
    inline void Build(const int node,const int Left,const int Right)
    {
        if(Left == Right)
        {
            aint[node] = value[Left];
            return ;
        }
        int mid = (Left+Right)/2;
        Build(2*node,Left,mid);
        Build(2*node+1,mid+1,Right);
        aint[node] = max(aint[2*node],aint[2*node+1]);
    }
    inline void Update(const int node,const int Left,const int Right,const int pos)
    {
        if(Left == Right)
        {
            aint[node] = value[Left];
            return ;
        }
        int mid = (Left+Right)/2;
        if(pos <= mid)
            Update(2*node,Left,mid,pos);
        else
            Update(2*node+1,mid+1,Right,pos);
        aint[node] = max(aint[2*node],aint[2*node+1]);
    }
    inline int Query(const int node,const int Left,const int Right,const int A,const int B)
    {
        if(A <= Left && Right <= B)
            return aint[node];
        int mid = (Left+Right)/2, x = 0, y = 0;
        if(A <= mid)
            x = Query(2*node,Left,mid,A,B);
        if(mid < B)
            y = Query(2*node+1,mid+1,Right,A,B);
        return max(x,y);
    }
    inline void Update(const int pos,const int val)
    {
        value[pos] = val;
        Update(1,1,n,pos);
    }
};
vector < int > Tree[NMAX], values[NMAX];
int nrfii[NMAX], nrlanturi, nivel[NMAX], lant[NMAX], nodtata[NMAX];
int pozitielant[NMAX], value[NMAX], nrnoduri[NMAX];
inline void DFS(const int node,const int Father)
{
    int fiumax = 0;
    ++nrfii[node];
    for(auto x=Tree[node].begin(); x!=Tree[node].end();++x)
        if(*x != Father)
        {
            nivel[*x] = nivel[node]+1;
            DFS(*x,node);
            nrfii[node] += nrfii[*x];
            if(nrfii[*x] > nrfii[fiumax])
                fiumax = *x;
        }
    if(fiumax == 0)
    {
        ++nrlanturi;
        nrnoduri[nrlanturi] = 1;
        lant[node] = nrlanturi;
        return ;
    }
    lant[node] = lant[fiumax];
    ++nrnoduri[lant[node]];
    for(auto x=Tree[node].begin(); x!=Tree[node].end();++x)
        if(*x != Father && *x != fiumax)
            nodtata[lant[*x]] = node;
}
SegmentTree T[NMAX];
int main()
{
    int n, m;
    freopen("heavypath.in","r",stdin);
    freopen("heavypath.out","w",stdout);
    scanf("%d %d\n",&n,&m);
    for(int i=1;i<=n;++i)
        scanf("%d ",&value[i]);
    for(int i=1;i<n;++i)
    {
        int x, y;
        scanf("%d %d\n",&x,&y);
        Tree[x].push_back(y);
        Tree[y].push_back(x);
    }
    nivel[1] = 1;
    DFS(1,0);
    for(int i=1;i<=nrlanturi;++i)
        values[i].resize(nrnoduri[i]);
    for(int i=1;i<=n;++i){
        pozitielant[i] = nivel[i] - nivel[nodtata[lant[i]]];
        values[lant[i]][pozitielant[i]-1] = value[i];
    }
    for(int i=1;i<=nrlanturi;++i)
        T[i] = SegmentTree(values[i]);
    while(m--)
    {
        int operation, x, y;
        scanf("%d %d %d\n",&operation,&x,&y);
        if(operation == 0)
            T[lant[x]].Update(pozitielant[x],y);
        else
        {
            int solution = 0;
            while(lant[x]!=lant[y])
            {
                if(nivel[nodtata[lant[x]]] < nivel[nodtata[lant[y]]])
                    swap(x,y);
                solution = max(solution,T[lant[x]].Query(1,1,nrnoduri[lant[x]],1,pozitielant[x]));
                x = nodtata[lant[x]];
            }
            if(nivel[x] > nivel[y])
                swap(x,y);
            //printf("x=%d y=%d %d %d\n",x,y,pozitielant[x],pozitielant[y]);
            solution = max(solution,T[lant[x]].Query(1,1,nrnoduri[lant[x]],pozitielant[x],pozitielant[y]));
            printf("%d\n",solution);
        }
    }
    return 0;
}