Cod sursa(job #1545557)

Utilizator sebinechitasebi nechita sebinechita Data 6 decembrie 2015 20:48:38
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.38 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
#define MAX 100005

typedef vector <int> :: iterator iter;
vector <int> G[MAX], P[MAX];
int n, nrOfPaths, ind, l, r;
int dad[MAX], weight[MAX], v[MAX], lvl[MAX], path[MAX], sum[MAX], indInPath[MAX], aint[4 * MAX];

void df(int nod, int d)
{
    dad[nod] = d;
    lvl[nod] = 1 + lvl[dad[nod]];
    weight[nod] = 1;
    int son = 0;
    for(iter it = G[nod].begin() ; it != G[nod].end() ; it++)
    {
        if(*it == d)
            continue;
        if(son == 0)
            son = *it;
        df(*it, nod);
        if(weight[*it] > weight[son])
            son = *it;
        weight[nod] += weight[*it];
    }
    if(son == 0)
    {
        P[++nrOfPaths].push_back(nod);
        path[nod] = nrOfPaths;
        indInPath[nod] = 0;
        return;
    }
    path[nod] = path[son];
    indInPath[nod] = P[path[nod]].size();
    P[path[nod]].push_back(nod);
}

void update(int nod, int st, int dr, int val, int dec)
{
    if(st == dr)
    {
        aint[dec + nod] = val;
        return;
    }
    int mij = (st + dr) >> 1;
    if(ind <= mij)
        update(2 * nod, st, mij, val, dec);
    else
        update(2 * nod + 1, mij + 1, dr, val, dec);
    aint[dec + nod] = max(aint[dec + 2 * nod], aint[dec + 2 * nod + 1]);
}

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

int main()
{
    int i, m, x, y, t;
    fin >> n >> m;
    for(i = 1 ; i <= n ; i++)
        fin >> v[i];
    for(int i = 1 ; i < n ; i++)
    {
        fin >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    df(1, 0);
    for(i = 1 ; i <= nrOfPaths ; i++)
        sum[i] = sum[i - 1] + P[i].size();
    for(i = 1 ; i <= n ; i++)
    {
        ind = indInPath[i] + 1;
        //cout << i << " " << ind << " " << P[path[i]].size() << " " << 4 * sum[path[i] - 1] << "\n";
        update(1, 1, P[path[i]].size(), v[i], 4 * sum[path[i] - 1]);
    }
    while(m--)
    {
        fin >> t;
        if(t == 0)
        {
            fin >> i;
            fin >> v[i];
            ind = indInPath[i] + 1;
            update(1, 1, P[path[i]].size(), v[i], 4 * sum[path[i] - 1]);
        }
        else
        {
            fin >> x >> y;
            int rez = 0;
            while(path[x] != path[y])
            {
                if(lvl[P[path[x]][P[path[x]].size() - 1]] < lvl[P[path[y]][P[path[y]].size() - 1]])
                    swap(x, y);
                i = x;
                l = indInPath[i] + 1;
                r = P[path[i]].size();
                rez = max(rez, query(1, 1, P[path[i]].size(), 4 * sum[path[i] - 1]));
                x = dad[P[path[x]][P[path[x]].size() - 1]];

            }
            l = indInPath[x] + 1;
            r = indInPath[y] + 1;

            if(l > r)
                swap(l, r);
           // cout << l << " " << r << "\n" << rez << "\n";;
            rez = max(rez, query(1, 1, P[path[x]].size(), 4 * sum[path[x] - 1]));
            fout << rez << "\n";
        }
    }
}