Cod sursa(job #2102334)

Utilizator FredyLup Lucia Fredy Data 8 ianuarie 2018 18:00:04
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.19 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

#define lim 100005
vector <int> G[lim], PATHS[lim];
int n, nrpaths, pos, aux;
int l, r;
int dad[lim], weight[lim], ini[lim], lvl[lim], path[lim], sum[lim], posInPath[lim], aint[4 * lim];

void dfs (int nod, int d)
{
    dad[nod] = d;
    lvl[nod] = 1 + lvl[d];
    weight[nod] = 1;
    int son = 0;
    for (auto it:G[nod])
    {
        if (it == d)    continue;
        if (son==0)    son=it;
        dfs (it, nod);
        if (weight[it] > weight[son])   son=it;
        weight[nod] += weight[it];
    }
    if (son==0)
    {
        PATHS[++nrpaths].push_back(nod);
        path[nod] = nrpaths;
        posInPath[nod] = 0;
        return;
    }
    path[nod] = path[son];
    posInPath[nod] = PATHS[path[nod]].size();
    PATHS[path[nod]].push_back(nod);
}

void update (int nod, int st, int dr, int val, int decalaj)
{
    if (st == dr)
    {
        aint[decalaj+nod] = val;
        return;
    }
    int mid = (st+dr)/2;
    if (pos <= mid) update (2*nod, st, mid, val, decalaj);
    else    update (2*nod+1, mid+1, dr, val, decalaj);
    aint[decalaj + nod] = max (aint[decalaj + 2 * nod], aint[decalaj + 2 * nod + 1]);
}

int query (int nod, int st, int dr, int decalaj)
{
    if (l<=st && dr<=r)
    {
        return aint[decalaj + nod];
    }
    int mid = (st+dr)/2;
    int rez = 0;
    if (l<=mid)    rez = max (rez, query (2*nod, st, mid, decalaj));
    if (mid+1<=r)   rez = max (rez, query (2*nod+1, mid+1, dr, decalaj));
    return rez;
}

int main()
{
    int m, x, y, t;
    fin>>n>>m;
    for (int i=1; i<=n; i++)    fin>>ini[i];
    for (int i=1; i<n; i++)
    {
        fin>>x>>y;
        G[x].push_back(y);
        G[y].push_back(x);
    }

    dfs (1, 0);
    for (int i=1; i<=nrpaths; i++)
        sum[i] = sum[i-1] + PATHS[i].size();

    for (int i=1; i<=n; i++)
    {
        pos = posInPath[i] + 1;
        update (1, 1, PATHS[path[i]].size(), ini[i], 4 * sum[path[i] - 1]);
    }

    while (m--)
    {
        fin>>t;
        if (t==0)
        {
            fin>>x;
            fin>>ini[x];
            pos = posInPath[x] + 1;
            update (1, 1, PATHS[path[x]].size(), ini[x], 4 * sum[path[x] - 1]);
        }
        else
        {
            fin>>x>>y;
            int rez=0;
            while (path[x] != path[y])
            {
                if (lvl[PATHS[path[x]][PATHS[path[x]].size()-1]] < lvl[PATHS[path[y]][PATHS[path[y]].size()-1]])
                    swap (x, y);
                aux = x;
                l = posInPath[aux] + 1;
                r = PATHS[path[aux]].size();
                rez = max (rez, query (1, 1, PATHS[path[aux]].size(), 4 * sum[path[aux]-1]));
                x = dad [PATHS[path[x]][PATHS[path[x]].size() - 1]];
            }
            l = posInPath[x] + 1;
            r = posInPath[y] + 1;
            if (l > r)
                swap (l, r);

            rez = max (rez, query (1, 1, PATHS[path[x]].size(), 4 * sum[path[x] - 1]));
            fout<<rez<<"\n";
        }
    }

    fout.close();
    return 0;
}