Cod sursa(job #1167330)

Utilizator tester9x9Tester9x9 tester9x9 Data 4 aprilie 2014 19:51:57
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.38 kb
#include <fstream>
#include <algorithm>
#include <vector>
#define NM 100010

using namespace std;

ifstream f("heavypath.in");
ofstream g("heavypath.out");

int N, M, K;
int V[NM];
int WPath[NM], WPos[NM], Level[NM];
int PathSize[NM], PathFather[NM];
int PathLevel[NM];
int Delay[NM], Size[NM];
vector<int> G[NM];
int AI[8*NM];
int L, R, P, val;

void Update (int node, int delay, int S, int D)
{
    if (S>=D)
    {
        AI[node + delay]=val;
        return;
    }

    int M=(S+D)/2;

    if (P<=M)
        Update(2*node, delay, S, M);
    else
        Update(2*node+1, delay, M+1, D);

    AI[node + delay] = max( AI[2*node + delay], AI[2*node+1 + delay]);
}

void Query (int node, int delay, int S, int D)
{
    if (L<=S && D<=R)
    {
        val=max(val, AI[node + delay]);
        return;
    }

    int M=(S+D)/2;

    if (L<=M)
        Query(2*node, delay, S, M);
    if (R>M)
        Query(2*node+1, delay, M+1, D);
}

void Read ()
{
    f >> N >> M;
    for (int i=1; i<=N; i++)
        f >> V[i];

    for (int i=1; i<N; i++)
    {
        int a, b;
        f >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
}

void DF (int node, int father)
{
    int bigson=-1, bigsize=-1;
    Size[node]=1;
    Level[node]=1+Level[father];

    for (vector<int>::iterator it=G[node].begin(); it!=G[node].end(); ++it)
    {
        if (*it==father)
            continue;

        DF(*it, node);
        Size[node]+=Size[*it];

        if (Size[*it]>bigsize)
        {
            bigsize=Size[*it];
            bigson=*it;
        }
    }

    if (bigson==-1)
    {
        ++K;
        WPath[node]=K;
        WPos[node]=1;
        PathSize[K]=1;

        return;
    }

    WPath[node]=WPath[bigson];
    PathSize[WPath[node]]++;
    WPos[node]=PathSize[WPath[node]];

    for (vector<int>::iterator it=G[node].begin(); it!=G[node].end(); ++it)
    {
        if (*it==father || *it==bigson)
            continue;

        PathFather[WPath[*it]]=node;
        PathLevel[WPath[*it]]=Level[node];
    }
}

void ComputeDelay ()
{
    for (int i=1; i<=K; i++)
        Delay[i]=Delay[i-1] + 4*PathSize[i-1] + 1;
}

void Build ()
{
    for (int i=1; i<=N; i++)
    {
        P=WPos[i];
        val=V[i];
        Update(1, Delay[WPath[i]], 1, PathSize[WPath[i]]);
    }
}

void GetANS (int x, int y)
{
    val=0;

    while (1)
    {
        if (PathLevel[WPath[x]]>PathLevel[WPath[y]])
            swap(x, y);

        if (WPath[x]==WPath[y])
        {
            L=min(WPos[x], WPos[y]);
            R=max(WPos[x], WPos[y]);

            Query(1, Delay[WPath[x]], 1, PathSize[WPath[x]]);
            return;
        }

        L=WPos[y];
        R=PathSize[WPath[y]];
        Query(1, Delay[WPath[y]], 1, PathSize[WPath[y]]);
        y=PathFather[WPath[y]];
    }
}

void Solve ()
{
    for (int i=1; i<=M; i++)
    {
        int t, x, y;
        f >> t >> x >> y;

        if (t==0)
        {
            P=WPos[x];
            val=y;
            Update(1, Delay[WPath[x]], 1, PathSize[WPath[x]]);
        }
        if (t==1)
        {
            GetANS(x, y);

            g << val << '\n';
        }
    }
}

int main ()
{
    Read();
    DF(1, 0);
    ComputeDelay();
    Build();
    Solve();

    f.close();
    g.close();

    return 0;
}