Cod sursa(job #1929767)

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

using namespace std;

int N,M;
int valori[NMAX];

vector<int> arbore[NMAX];
vector<vector<int> > lant;
vector<vector<int> > intervale;

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);
    }
}

void dfs(int nod,int t)
{
    nivel[nod]=nivel[t]+1;
    greutati[nod]=1;
    int nr_fii=0;
    int greutate_maxima_fii=0;
    int fiu_maxim;
    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;
            }

            nr_fii++;
        }
    if(nr_fii==0) ///e frunza
    {
        vector<int> aux;
        aux.push_back(nod);
        lant.push_back(aux);
        apartine[nod]=lant.size()-1;
        poz_in_lant[nod]=1;
    }
    else
    {
        apartine[nod]=apartine[fiu_maxim];
        lant[apartine[nod]].push_back(nod);
        poz_in_lant[nod]=lant[apartine[nod]].size();
    }

    t_lant[apartine[nod]]=t;

}

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
        {
            int a = rezolvaQ(x,y);
            printf("%d\n",a);
        }
    }
}


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