Cod sursa(job #1929772)

Utilizator PaulCbnCiobanu Paul PaulCbn Data 18 martie 2017 02:50:11
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.01 kb
#include <iostream>
#include <cstdio>
#include <vector>
#define NMAX 100005

using namespace std;

int N,M;

vector<int> arbore[NMAX];
vector<vector<int> > lant,intervale;
int valori[NMAX];
int greutati[NMAX];
int apartine[NMAX];
int poz_in_lant[NMAX];
int t_lant[NMAX];
int nivel[NMAX];

void citire()
{
    scanf("%d%d",&N,&M);
    for(int i=1; i<=N; i++)
        scanf("%d",&valori[i]);
    for(int i=1; i<=N-1; i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        arbore[x].push_back(y);
        arbore[y].push_back(x);
    }
}
vector<int> aux;
void dfs(int nod,int t)
{
    nivel[nod]=nivel[t]+1;
    greutati[nod]=1;
    int greutate_maxima_fii=-1;
    int fiu_maxim=-1;
    for(vector<int>::iterator ii=arbore[nod].begin(); ii!=arbore[nod].end(); ii++)
        if(*ii != t)
        {
            dfs(*ii,nod);
            greutati[nod]+=greutati[*ii];
            if(greutate_maxima_fii < greutati[*ii])
            {
                greutate_maxima_fii = greutati[*ii];
                fiu_maxim = *ii;
            }
        }
    if(greutate_maxima_fii==-1) ///e frunza
    {
        aux.clear();
        aux.push_back(nod);
        lant.push_back(aux);
        apartine[nod]=lant.size()-1;
        t_lant[apartine[nod]]=t;
        poz_in_lant[nod]=1;
    }
    else
    {
        apartine[nod]=apartine[fiu_maxim];
        lant[apartine[nod]].push_back(nod);
        t_lant[apartine[nod]]=t;
        poz_in_lant[nod]=lant[apartine[nod]].size();
    }
}

void update(vector<int> &interval,int val,int st,int dr,int nod_curent, int poz)
{
    if(st==dr)
    {
        interval[nod_curent]=val;
        return;
    }
    int mij = (st+dr)/2;

    if(poz<=mij)
        update(interval,val,st,mij,nod_curent*2,poz);
    else
        update(interval,val,mij+1,dr,nod_curent*2+1,poz);
    interval[nod_curent] = max(interval[nod_curent*2],interval[nod_curent*2+1]);
}

void query(vector<int> &interval,int x,int y,int st,int dr, int nod_curent, int &maxim)
{
    if(x<=st && dr<=y)
    {
        maxim = max(maxim,interval[nod_curent]);
        return;
    }

    int mij = (st+dr)/2;

    if(x <= mij)
        query(interval,x,y,st,mij,nod_curent*2,maxim);
    if(mij < y)
        query(interval,x,y,mij+1,dr,nod_curent*2+1,maxim);
}

int rezolvaQ(int x,int y)
{
    int n1,n2;
    int maxim = 0;

    n1 = nivel[t_lant[apartine[x]]];
    n2 = nivel[t_lant[apartine[y]]];
    while(apartine[x] != apartine[y])
    {
        int m = 0;
        if(n1 > n2)
        {
            int p1 = poz_in_lant[x];
            query(intervale[apartine[x]],p1,lant[apartine[x]].size(),1,lant[apartine[x]].size(),1,m);
            x = t_lant[apartine[x]];
        }
        else
        {
            int p2 = poz_in_lant[y];
            query(intervale[apartine[y]],p2,lant[apartine[y]].size(),1,lant[apartine[y]].size(),1,m);
            y = t_lant[apartine[y]];
        }
        maxim = max(maxim,m);

        n1 = nivel[t_lant[apartine[x]]];
        n2 = nivel[t_lant[apartine[y]]];
    }
    int m = 0;
    int p1 = poz_in_lant[x];
    int p2 = poz_in_lant[y];
    query(intervale[apartine[x]],min(p1,p2),max(p1,p2),1,lant[apartine[x]].size(),1,m);
    maxim = max(maxim,m);
    return maxim;
}


void genereaza()
{
    for(int i=0; i<lant.size(); i++)
    {
        vector<int> aux;
        int n = lant[i].size();
        aux.resize(n*4+1,0);
        intervale.push_back(aux);
        for(int j=0; j<n; j++)
            update(intervale[i],valori[lant[i][j]],1,n,1,j+1);
    }
}

void rezolva()
{
    for(int i=1; i<=M; i++)
    {
        int q,x,y;
        scanf("%d%d%d",&q,&x,&y);
        if(q == 0)
            update(intervale[apartine[x]],y,1,lant[apartine[x]].size(),1,poz_in_lant[x]);
        else
            printf("%d\n",rezolvaQ(x,y));
    }
}

int main()
{
    freopen("heavypath.in","r",stdin);
    freopen("heavypath.out","w",stdout);
    citire();
    dfs(1,0);
    genereaza();
    rezolva();
    return 0;
}