Cod sursa(job #2149697)

Utilizator tziplea_stefanTiplea Stefan tziplea_stefan Data 2 martie 2018 21:35:11
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.68 kb
#include <fstream>
#include <vector>
#define VAL 100005

using namespace std;

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

int N, M, i, j, A, B, NRL, mx, son, nr, T, X, Y, cop, ANS, be, en;
int elem[VAL], niv[VAL], lant[VAL], poz[VAL], subarb[VAL], fat[VAL];
bool par[VAL];
vector <int> G[VAL], L[VAL], AINT[VAL];
vector <int> :: iterator it;

void DFS(int nod)
{
    int mx, son;
    vector <int> :: iterator it;
    nr=0;
    subarb[nod]++;
    par[nod]=true;
    for (it=G[nod].begin(); it!=G[nod].end(); it++)
      if (par[*it]==false)
        nr++;
    if (nr==0)
    {
        NRL++;
        L[NRL].push_back(0);
        L[NRL].push_back(nod);
        lant[nod]=NRL;
        poz[nod]=L[NRL].size()-1;
        return;
    }
    mx=son=0;
    for (it=G[nod].begin(); it!=G[nod].end(); it++)
    {
        if (par[*it]==true)
          continue;
        niv[*it]=niv[nod]+1;
        fat[*it]=nod;
        DFS(*it);
        if (mx<subarb[*it])
        {
            mx=subarb[*it];
            son=*it;
        }
        subarb[nod]+=subarb[*it];
    }
    L[lant[son]].push_back(nod);
    lant[nod]=lant[son];
    poz[nod]=L[lant[nod]].size()-1;
}

void Initializare(int nod, int be, int en)
{
    if (be==en)
      AINT[i][nod]=elem[L[i][be]];
    else
    {
        int mid=(be+en) / 2;
        Initializare(2*nod, be, mid);
        Initializare(2*nod+1, mid+1, en);
        AINT[i][nod]=max(AINT[i][2*nod], AINT[i][2*nod+1]);
    }
}

void Update(int l, int nod, int be, int en, int poz)
{
    if (be==en)
      AINT[l][nod]=elem[L[l][be]]=Y;
    else
    {
        int mid=(be+en) / 2;
        if (be<=poz && poz<=mid)
          Update(l, 2*nod, be, mid, poz);
        if (mid+1<=poz && poz<=en)
          Update(l, 2*nod+1, mid+1, en, poz);
        AINT[l][nod]=max(AINT[l][2*nod], AINT[l][2*nod+1]);
    }
}

void Query(int l, int nod, int be, int en, int st, int dr)
{
    if (st<=be && en<=dr)
    {
        ANS=max(ANS, AINT[l][nod]);
        return;
    }
    int mid=(be+en) / 2;
    if (max(be, st)<=min(mid, dr))
      Query(l, 2*nod, be, mid, st, dr);
    if (max(mid+1, st)<=min(en, dr))
      Query(l, 2*nod+1, mid+1, en, st, dr);
}

int main()
{
    fin >> N >> M;
    for (i=1; i<=N; i++)
      fin >> elem[i];
    for (i=1; i<N; i++)
    {
        fin >> A >> B;
        G[A].push_back(B);
        G[B].push_back(A);
    }
    niv[1]=1;
    DFS(1);
    for (i=1; i<=NRL; i++)
    {
        cop=1;
        while (cop<2*L[i].size()-3)
          cop*=2;
        AINT[i].push_back(cop);
        for (j=1; j<=cop; j++)
          AINT[i].push_back(0);
        Initializare(1, 1, L[i].size()-1);
        for (j=1; j<L[i].size(); j++)
          poz[L[i][j]]=j;
    }
    for (i=1; i<=M; i++)
    {
        fin >> T >> X >> Y;
        if (T==0)
          Update(lant[X], 1, 1, L[lant[X]].size()-1, poz[X]);
        else
        {
            ANS=0;
            while (lant[X]!=lant[Y])
            {
                if (L[lant[X]].size()<L[lant[Y]].size())
                {
                    be=poz[X];
                    en=L[lant[X]].size()-1;
                   // Query(lant[X], 1, 1, L[lant[X]].size()-1, be, en);
                    X=L[lant[X]][en];
                    X=fat[X];
                }
                else
                {
                    be=poz[Y];
                    en=L[lant[Y]].size()-1;
                   // Query(lant[Y], 1, 1, L[lant[Y]].size()-1, be, en);
                    Y=L[lant[Y]][en];
                    Y=fat[Y];
                }
            }
            be=min(poz[X], poz[Y]);
            en=max(poz[X], poz[Y]);
            //Query(lant[X], 1, 1, L[lant[X]].size()-1, be, en);
            fout << ANS << '\n';
        }
    }
    fin.close();
    fout.close();
    return 0;
}