Cod sursa(job #975175)

Utilizator crisbodnarCristian Bodnar crisbodnar Data 19 iulie 2013 12:42:33
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.24 kb
//are buguri

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

#define newn a[x][i]
#define nodl lant[i][j]
#define mid ((st + dr) >> 1)
#define fiu1 (nod << 1)
#define fiu2 (fiu1 + 1)

using namespace std;

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

const int N = 100010;

int n, m, nrp = 1;
vector <int> a[N], lant[N], v(N), nrnod(N), height(N), place(N), tata(N), poz(N), arb(4*N);
vector <bool> viz(N), uz(N);

void update(int nod, int st, int dr, int poz, int val, int fix)
{
    if(st == dr)
    {
        arb[nod+fix] = val;
        return ;
    }
    if(poz <= mid)
        update(fiu1, st, mid, poz, val, fix);
    else
        update(fiu2, mid+1, dr, poz, val, fix);
    arb[nod+fix] = max(arb[fiu1 + fix], arb[fiu2 + fix]);
}

int query(int nod, int st, int dr, int lvs, int lvd, int fix)
{
    if(lvs <= st && dr <= lvd)
        return arb[nod+fix];
    int rez = 0;
    if(lvs <= mid) rez = max(rez, query(fiu1, st, mid, lvs, lvd, fix));
    else rez = max(rez, query(fiu2, mid+1, dr, lvs, lvd, fix));
    return rez;
}

void dfs(int x, int level)
{
    nrnod[x]++;
    height[x] = level;
    for(unsigned i=0; i<a[x].size(); i++)
        if(!viz[newn])
        {
            dfs(newn, level+1);
            nrnod[x] += nrnod[newn];
        }
}

bool cmp(const int &a, const int &b){ return nrnod[a] > nrnod[b];}

void heavy_path(int x, int path)
{
    viz[x] = 0;
    place[x] = path;
    lant[path].push_back(x);
    for(unsigned i=0; i<a[x].size(); i++)
        if(viz[newn])
        {
            if(!uz[x])
            {
                uz[x] = 1;
                heavy_path(newn, path);
            }
            else
            {
                tata[++nrp] = x;
                heavy_path(newn, nrp);
            }
        }
}

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

    dfs(1, 1);
    for(int i=1; i<=n; i++)
        sort(a[i].begin(), a[i].end(), cmp);
    heavy_path(1, 1);
    for(int i=1; i<=nrp; i++)
    {
        poz[i] = poz[i-1] + lant[i-1].size() * 4;
        for(unsigned j=0; j<lant[i].size(); j++)
            update(1, 1, lant[i].size(), height[nodl] - height[tata[place[nodl]]], v[nodl], poz[i]);
    }

    while(m--)
    {
        bool t; int x, y;
        fin>>t>>x>>y;
        if(!t) update(1, 1, lant[place[x]].size(), height[x] - height[tata[place[x]]], y, poz[place[x]]);
        else{
                int sol = -1;
                while(place[x] != place[y])
                {
                    if(height[tata[place[x]]] < height[tata[place[y]]]) swap(x, y);
                    sol = max (sol, query(1, 1, lant[place[x]].size(), 1, height[x] - height[tata[place[x]]], poz[place[x]]));
                    x = tata[place[x]];
                }
                if(height[x] < height[y]) swap(x, y);
                sol = max(sol, query(1, 1, lant[place[x]].size(), height[y] - height[tata[place[x]]], height[x] - height[tata[place[x]]], poz[place[x]]));
                fout<<sol<<'\n';
            }
    }
    return 0;
}