Cod sursa(job #1126198)

Utilizator crisbodnarCristian Bodnar crisbodnar Data 26 februarie 2014 21:51:48
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.23 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>

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

using namespace std;

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

const int NMAX = 1e5 + 100;
const int oo = 0x3f3f3f3f;

int N, M, nrp = 1, V[NMAX], PLACE[NMAX], T[NMAX], DIM[NMAX], H[NMAX], P[NMAX], ARB[NMAX * 4];
vector <int> G[NMAX], LANT[NMAX];
vector <bool> viz(NMAX), uz(NMAX);

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

void DFS(int nod, int height)
{
    viz[nod] = 1;
    DIM[nod]++;
    H[nod] = height;
    for(unsigned i = 0; i < G[nod].size(); i++)
        if(!viz[newn])
        {
            DFS(newn, height + 1);
            DIM[nod] += DIM[newn];
        }
}

void Path(int nod, int path)
{
    viz[nod] = 0;
    PLACE[nod] = path;
    LANT[path].push_back(nod);
    for(unsigned i = 0; i < G[nod].size(); i++)
        if(viz[newn])
        {
            if(!uz[nod])
            {
                uz[nod] = 1;
                Path(newn, path);
            }
            else
            {
                T[++nrp] = nod;
                Path(newn, nrp);
            }
        }
}

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 left, int right, int fix)
{
    if(left > dr || st > right) return -oo;

    if(left <= st && dr <= right)
        return ARB[nod + fix];

    int rez = -oo;
    rez = max(rez, Query(fiu1, st, mid, left, right, fix));
    rez = max(rez, Query(fiu2, mid + 1, dr, left, right, fix));

    return rez;
}

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;
        G[x].push_back(y);
        G[y].push_back(x);
    }

    DFS(1, 1);
    for(int i = 1; i <= N; i++)
        sort(G[i].begin(), G[i].end(), cmp);
    Path(1, 1);

    for(int i = 1; i <= nrp; i++)
    {
        P[i] = P[i - 1] + LANT[i - 1].size() * 4;
        for(unsigned j = 0; j < LANT[i].size(); j++)
            Update(1, 1, LANT[i].size(), H[nodl] - H[T[i]], V[nodl], P[i]);
    }

    while(M--)
    {
        int tip, x, y;
        fin >> tip >> x >> y;
        if(!tip) Update(1, 1, LANT[PLACE[x]].size(), H[x] - H[T[PLACE[x]]], y, P[PLACE[x]]);
        else
        {
            int sol = -1;
            while(PLACE[x] != PLACE[y])
            {
                if(H[T[PLACE[x]]] < H[T[PLACE[y]]]) swap(x, y);
                sol = max(sol, Query(1, 1, LANT[PLACE[x]].size(), 1, H[x] - H[T[PLACE[x]]], P[PLACE[x]]));
                x = T[PLACE[x]];
            }
            if(H[x] < H[y]) swap(x, y);
            sol = max(sol, Query(1, 1, LANT[PLACE[x]].size(), H[y] - H[T[PLACE[x]]], H[x] - H[T[PLACE[x]]], P[PLACE[x]]));
            fout << sol << '\n';
        }
    }
    return 0;
}