Cod sursa(job #1619518)

Utilizator AdrianaMAdriana Moisil AdrianaM Data 28 februarie 2016 16:54:08
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.99 kb
#include <fstream>
#include <vector>
using namespace std;

ifstream is("heavypath.in");
ofstream os("heavypath.out");

using VI = vector<int>;
using VVI = vector<VI>;

class ST{
public:
    ST(const VI &a)
    {
        for ( n = 1; n < a.size(); n <<= 1 );
        arb = VI(2 * n);
        for ( int i = 0; i < a.size(); ++i )
            arb[n + i] = a[i];
        for ( int i = n - 1; i; --i )
            arb[i] = max(arb[2 * i], arb[2 * i + 1]);
    }
    void Update(int poz, int val)
    {
        arb[poz += n] = val;
        for ( poz >>= 1; poz; poz >>= 1 )
            arb[poz] = max(arb[2 * poz], arb[2 * poz + 1]);
    }
    int Query(int st, int dr)
    {
        st += n;
        dr += n;
        int answ = 0;
        while ( st <= dr )
        {
            answ = max(answ, max(arb[st], arb[dr]));
            st = ( st + 1 ) >> 1;
            dr = ( dr - 1 ) >> 1;
        }
        return answ;
    }
private:
    int n;
    VI arb;
};

int n, m, N;
VI val, t, h, pId, poz, nrfii;
VVI g, paths;
vector<ST> st;

void Read();
void Build();
void DF(int nod);
int Query(int x, int y);

int main()
{
    Read();
    Build();
    int tip, x, y;
    while ( m-- )
    {
        is >> tip >> x >> y;
        if ( !tip )
        {
            st[pId[x]].Update(poz[x], y);
        }
        else
            os << Query(x, y) << "\n";
    }
    is.close();
    os.close();
    return 0;
}

int Query(int x, int y)
{
    if ( x == 0 )
        x = paths[pId[y]].back();
    if ( pId[x] == pId[y] )
    {
        if ( poz[x] > poz[y] )
            swap(x, y);
        return st[pId[x]].Query(poz[x], poz[y]);
    }
   // if ( h[paths[pId[x]].back()] < h[paths[pId[y]].back()] )
   //    swap(x, y);
    return max(st[pId[x]].Query(poz[x], paths[pId[x]].size() - 1), Query(t[paths[pId[x]].back()], y));
}

void Read()
{
    is >> n >> m;
    val = t = VI(n + 1);
    g = VVI(n + 1);
    for ( int i = 1; i <= n; ++i )
        is >> val[i];
    int x, y;
    for ( int i = 1; i < n; ++i )
    {
        is >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
}

void Build()
{
    t = h = pId = poz = nrfii = VI(n + 1);
    DF(1);
    VI a;
    for ( const auto &p : paths )
    {
        a.clear();
        for ( const auto &i : p )
            a.push_back(val[i]);
        st.push_back(a);
    }
}

void DF(int nod)
{
    int hs = 0;
    nrfii[nod] = 1;
    for ( const auto &nodv : g[nod] )
    {
        if ( nodv == t[nod] )
            continue;
        t[nodv] = nod;
        h[nodv] = h[nod] + 1;
        DF(nodv);
        nrfii[nod] += nrfii[nodv];
        if ( nrfii[nodv] > nrfii[hs] )
            hs = nodv;
    }
    if ( g[nod].size() == 1 )
    {
        pId[nod] = paths.size();
        poz[nod] = 0;
        paths.push_back(VI(1, nod));
    }
    else
    {
        pId[nod] = pId[hs];
        poz[nod] = paths[pId[nod]].size();
        paths[pId[nod]].push_back(nod);
    }
}