Cod sursa(job #1208576)

Utilizator angelaAngela Visuian angela Data 16 iulie 2014 07:50:16
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.38 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

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

class ST {
  public:
    ST(const vector<int> &values)
    {
        for (N = 1; N < int(values.size()); N <<= 1);  // N = cea mai mica putere a lui 2, mai mare decat size()

        tree = vector<int>(2 * N, 0);    // 4 n
        for (int i = 0; i < int(values.size()); ++i) // valorile innitiale puse pe poz [n, .. 2n -1]
            tree[N + i] = values[i];
        for (int x = N - 1; x > 0; --x)
            tree[x] = max(tree[2 * x], tree[2 * x + 1]);
    }

    void Update(int where, const int value) 
    {
		
        tree[where += N] = value;
        for (where >>= 1; where > 0; where >>= 1)
            tree[where] = max(tree[2 * where], tree[2 * where + 1]);
    }

    int Query(int l, int r) const 
    {
        l += N;  r += N;
        int vmax = 0;
        while (l <= r) 
        {
            vmax = max(vmax, max(tree[l], tree[r]));
            l = (l + 1) / 2;
            r = (r - 1) / 2;
        }
        return vmax;
    }

  private:
    int N;
    vector<int> tree;
};

vector<vector<int> > T, paths;
int V;
vector<int> v, t, nr, h, pId, pos;
vector<ST> st;

void DFS(const int x) 
{
    int hs(-1);
    nr[x] = 1;
    for ( auto y : T[x] )
    {
        if (y == t[x])
            continue;
        t[y] = x;
        h[y] = h[x] + 1;
        DFS(y);
        nr[x] += nr[y];
        if (hs == -1 || nr[y] > nr[hs])
            hs = y;
    }
    if (hs == -1 ) // frunza
    {
        pId[x] = int(paths.size());
        paths.push_back(vector<int>());
    } 
    else 
        pId[x] = pId[hs];
    
    pos[x] = int(paths[pId[x]].size()); // va fi pus la sfarsit (vechea poz n)
    paths[pId[x]].push_back(x);
}

void BuildHeavyPath() 
{
    t = pId = vector<int>(V, -1); // V e nr de noduri a arborelui
    nr = vector<int>(V, 0);                // nr[i] - ne nodur idin subarb cu rad in i
    h = vector<int>(V, -1);              // adancimea in Dfs
    pos = vector<int>(V, -1); // -1  pe ce poz in lantul curent e x
    h[0] = 0;
    DFS(0);
	for (int p = 0; p < int(paths.size()); ++p) 
	{
        vector<int> pathValues; 
        
        for (int x : paths[p])
            pathValues.push_back(v[x]);
     
        st.push_back(ST(pathValues));
    }
}

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

int main() 
{
    int Q;
    fin >> V >> Q;
    v = vector<int>(V);
    for (int x = 0; x < V; ++x)
        fin >> v[x];
    T = vector< vector<int> >(V, vector<int>());
    for (int e = 1; e < V; ++e) 
    {
        int x, y;
        fin >> x >> y;
        x--,  y--;
        T[x].push_back(y);
        T[y].push_back(x);
    }
    BuildHeavyPath();
    int op, x, y, val;
    for (; Q > 0; --Q) 
    {
        fin >> op;
        if (op == 0) 
        {
            fin >> x >> val;
            v[x] = val;
            st[pId[x - 1]].Update(pos[x - 1], val);
        } 
        else 
        {
            fin >> x >> y;
            fout << Query(x - 1, y - 1) << "\n";
        }
    }
    fin.close();
    fout.close();
    return 0;
}