Cod sursa(job #1190414)

Utilizator andreiiiiPopa Andrei andreiiii Data 25 mai 2014 12:45:43
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4 kb
#include <algorithm>
#include <cstdio>
#include <vector>

using namespace std;

const int Nmax = 100005;

class SegmentTree{
public:
    SegmentTree(const int _n=0, vector<int> _vals=vector<int>()):
        n(_n),
        aint(vector<int>(5*_n+2)),
        vals(_vals)
        {
            if(_n) Build(1, 1, n);
        }
    void update(const int poz, const int val)
    {
        X=poz;
        Y=val;
        Update(1, 1, n);
    }
    int query(const int st, const int dr)
    {
        ret=0;
        X=st;
        Y=dr;
        Query(1, 1, n);
        return ret;
    }
private:
    int n, X, Y, ret;
    vector<int> aint, vals;
    void Build(int nod, int l, int r)
    {
        if(l==r)
        {
            aint[nod]=vals[l];
            return;
        }
        int mid=(l+r)/2;
        Build(2*nod, l, mid);
        Build(2*nod+1, mid+1, r);
        aint[nod]=max(aint[2*nod], aint[2*nod+1]);
    }
    void Update(int nod, int l, int r)
    {
        if(l==r)
        {
            aint[nod]=Y;
            return;
        }
        int mid=(l+r)/2;
        if(X<=mid) Update(2*nod, l, mid);
        else Update(2*nod+1, mid+1, r);
        aint[nod]=max(aint[2*nod], aint[2*nod+1]);
    }
    void Query(int nod, int l, int r)
    {
        if(X<=l&&r<=Y)
        {
            if(aint[nod]>ret) ret=aint[nod];
            return;
        }
        int mid=(l+r)/2;
        if(X<=mid) Query(2*nod, l, mid);
        if(Y>mid) Query(2*nod+1, mid+1, r);
    }
};

int A[Nmax], Path[Nmax], Nr[Nmax], Pos[Nmax], Lvl[Nmax], Father[Nmax];
vector<int> G[Nmax], Paths[Nmax], values;

int N, Nrpaths;

SegmentTree STrees[Nmax];

void Dfs1(const int node, const int father)
{
    if (father) G[node].erase(find(G[node].begin(), G[node].end(), father));

    Nr[node] = 1;

    int noden = 0;
    for (auto p: G[node])
    {
        Dfs1(p, node);

        Nr[node] += Nr[p];
        if (Nr[p] > Nr[noden])
            noden = p;
    }

    if (!noden) Path[node] = ++Nrpaths;
    else Path[node] = Path[noden];

    Paths[Path[node]].push_back(node);
}

void Dfs2(const int node)
{
    for (auto p: G[node])
    {
        if (Path[node] != Path[p])
        {
            Lvl[Path[p]] = Lvl[Path[node]] + 1;
            Father[Path[p]] = node;
        }

        Dfs2(p);
    }
}

int main()
{
    freopen("heavypath.in", "r", stdin);
    freopen("heavypath.out", "w", stdout);

    int Q;
    scanf("%d%d", &N, &Q);

    for (int i = 1; i <= N; i++)
        scanf("%d", &A[i]);

    for (int i = 1; i < N; i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);

        G[x].push_back(y);
        G[y].push_back(x);
    }

    Dfs1(1, 0);

    for (int i = 1; i <= Nrpaths; i++)
    {
        Paths[i].push_back(0);
        reverse(Paths[i].begin(), Paths[i].end());

        for (int j = 0; j < int(Paths[i].size()); j++)
        {
            Pos[Paths[i][j]] = j;
            values.push_back(A[Paths[i][j]]);
        }

        STrees[i] = SegmentTree(values.size() - 1, values);

        Paths[i].clear();
        values.clear();
    }

    Dfs2(1);

    while (Q--)
    {
        int op, x, y;
        scanf("%d%d%d", &op, &x, &y);

        if (op == 0)
        {
            STrees[Path[x]].update(Pos[x], y);
        }
        else
        {
            int i = Path[x], j = Path[y], Sol = 0;

            while (i != j)
            {
                if (Lvl[i] > Lvl[j])
                {
                    Sol = max(Sol, STrees[i].query(0, Pos[x]));

                    x = Father[i];
                    i = Path[x];
                }
                else
                {
                    Sol = max(Sol, STrees[j].query(0, Pos[y]));

                    y = Father[j];
                    j = Path[y];
                }

                Sol = max(Sol, STrees[i].query(min(Pos[x], Pos[y]), max(Pos[x], Pos[y])));
           }

           printf("%d\n", Sol);
        }
    }
}