Cod sursa(job #1934728)

Utilizator VladG26Ene Vlad-Mihai VladG26 Data 21 martie 2017 19:12:11
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.33 kb
#include <iostream>
#include <cstdio>
#include <vector>

using namespace std;

int m,n,vValNod[100001],vTati[100001],indiceLant;
int vGreutate[100001],vNiv[100001],lantCorespunzator[100001],pozInLant[100001];

vector <int> lanturi[100001];
vector <int> AI[100001];
vector <int> G[100001];

void citire()
{
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)
        scanf("%d",&vValNod[i]);

    int aux1,aux2;
    for(int i=1; i<n; i++)
    {
        scanf("%d%d",&aux1,&aux2);
        vTati[aux2]=aux1;
        G[aux1].push_back(aux2);
    }
    for(int i=1; i<=n; i++)
        vGreutate[i]=1;
}
void dfs(int nod)
{
    int maxx=0,nodmax=0;
    vector <int> ::iterator IT;
    if(G[nod].size()==0)
    {
        indiceLant++;
        lantCorespunzator[nod]=indiceLant;
        lanturi[indiceLant].push_back(nod);
        pozInLant[nod]=1;
    }
    else
    {
        for(IT=G[nod].begin(); IT!=G[nod].end(); IT++)
        {
            vNiv[*IT]=vNiv[nod]+1;
            dfs(*IT);
            vGreutate[nod]+=vGreutate[*IT];
            if(maxx<vGreutate[*IT])
            {
                maxx=vGreutate[*IT];
                nodmax=*IT;
            }
        }
        lanturi[lantCorespunzator[nodmax]].push_back(nod);
        lantCorespunzator[nod]=lantCorespunzator[nodmax];
        pozInLant[nod]=pozInLant[nodmax]+1;
    }
}
void buildArb(int nrLant,int pai,int st,int dr)
{
    if(st==dr)
    {
        AI[nrLant][pai]=vValNod[lanturi[nrLant][st]];
        return;
    }
    int mij=(st+dr)/2;

    buildArb(nrLant,2*pai,st,mij);
    buildArb(nrLant,2*pai+1,mij+1,dr);

    AI[nrLant][pai]=max(AI[nrLant][2*pai],AI[nrLant][2*pai+1]);
}
void updateArbore(int nrLant,int pai,int st,int dr,int cetrebuieSchimbat,int cuCeTrebuieSchimbat)
{
    if(st==dr)
    {
        AI[nrLant][pai]=cuCeTrebuieSchimbat;
        return;
    }
    int mij=(st+dr)/2;

    if(mij>=cetrebuieSchimbat)
        updateArbore(nrLant,2*pai,st,mij,cetrebuieSchimbat,cuCeTrebuieSchimbat);
    else
        updateArbore(nrLant,2*pai+1,mij+1,dr,cetrebuieSchimbat,cuCeTrebuieSchimbat);
    AI[nrLant][pai]=max(AI[nrLant][2*pai],AI[nrLant][2*pai+1]);
}

int maxInterval;
void aflareMaxim(int nrLant,int pai,int st,int dr,int intervalS,int intervalD)
{
    if(st>=intervalS&&dr<=intervalD)
    {
        maxInterval=max(maxInterval,AI[nrLant][pai]);
        return;
    }

    int mij=(st+dr)/2;
    if(mij>=intervalS)
        aflareMaxim(nrLant,pai*2,st,mij,intervalS,intervalD);
    if(mij<intervalD)
        aflareMaxim(nrLant,pai*2+1,mij+1,dr,intervalS,intervalD);

}

int main()
{
    freopen("heavypath.in","r",stdin);
    freopen("heavypath.out","w",stdout);
    citire();
    dfs(1);
    for(int i=1; i<=indiceLant; i++)
    {
        for(int j=0; j<lanturi[i].size(); j++)
            printf("%d ",lanturi[i][j]);
        printf("\n");
    }

    for(int i=1; i<=indiceLant; i++)
    {
        AI[i].resize(4*lanturi[i].size());
        buildArb(i,1,0,lanturi[i].size()-1);
    }

    int t,aux1,aux2;

    for(int i=1; i<=m; i++)
    {
        scanf("%d%d%d",&t,&aux1,&aux2);
        if(t==0)
        {
            updateArbore(lantCorespunzator[aux1],1,0,lanturi[lantCorespunzator[aux1]].size(),aux1,aux2);
        }
        else
        {
            maxInterval=0;
            while(lantCorespunzator[aux1]!=lantCorespunzator[aux2])
            {
                if(vNiv[*(lanturi[lantCorespunzator[aux1]].end()-1)]<vNiv[*(lanturi[lantCorespunzator[aux2]].end()-1)])
                {
                    aflareMaxim(lantCorespunzator[aux1],1,0,lanturi[lantCorespunzator[aux1]].size()-1,pozInLant[aux1],lanturi[lantCorespunzator[aux1]].size());
                    aux1=vTati[*(lanturi[lantCorespunzator[aux1]].end()-1)];
                }
                else
                {
                    aflareMaxim(lantCorespunzator[aux2],1,0,lanturi[lantCorespunzator[aux2]].size()-1,pozInLant[aux2],lanturi[lantCorespunzator[aux2]].size());
                    aux2=vTati[*(lanturi[lantCorespunzator[aux2]].end()-1)];
                }
            }
            aflareMaxim(lantCorespunzator[aux1],1,1,lanturi[lantCorespunzator[aux1]].size(),min(pozInLant[aux1],pozInLant[aux2]),max(pozInLant[aux1],pozInLant[aux2]));
            printf("%d\n",maxInterval);
        }
    }
    return 0;
}