Cod sursa(job #1412686)

Utilizator oana28Oana Mitoiu oana28 Data 1 aprilie 2015 13:53:00
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.94 kb
#include<fstream>
#include<vector>
using namespace std;
#define NMAX 100050
#define fius (nod<<1)
#define fiud fius+1
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
vector <int> v[NMAX],G[NMAX];
int n,m,t,x,y,nr,a[NMAX],D[NMAX],L[NMAX],Poz[NMAX];
int A[NMAX<<2],T[NMAX],Size[NMAX],Start[NMAX],Niv[NMAX];
void dfs(int nod, int tata, int niv)
{
    int i,fiu,hfiu;
    D[nod]=1, T[nod]=tata, Niv[nod]=niv;
    for (i=0;i<v[nod].size();++i)
    {
        fiu=v[nod][i];
        if (!D[fiu])
        {
            hfiu=fiu;
            dfs(fiu,nod,niv+1);
            D[nod]+=D[fiu];
        }
    }
    if (D[nod]==1)
    {
        L[nod]=++nr;
        G[nr].push_back(nod);
        return ;
    }
    for (i=0;i<v[nod].size();++i)
        if (v[nod][i]!=tata && D[v[nod][i]]>D[hfiu])
            hfiu=v[nod][i];
    L[nod]=L[hfiu];
    G[L[nod]].push_back(nod);
}
void update(int nod, int st, int dr, int poz, int x, int decalaj)
{
    if (st==dr)
    {
        A[nod+decalaj]=x;
        return ;
    }
    int mij=(st+dr)>>1;
    if (poz<=mij) update(fius,st,mij,poz,x,decalaj);
    else update(fiud,mij+1,dr,poz,x,decalaj);
    A[nod+decalaj]=max(A[fius+decalaj],A[fiud+decalaj]);
}
int query(int nod, int st, int dr, int a, int b, int decalaj)
{
    if (a<=st && dr<=b)
        return A[nod+decalaj];
    int mij=(st+dr)>>1,q1=0,q2=0;
    if (a<=mij) q1=query(fius,st,mij,a,b,decalaj);
    if (mij<b) q2=query(fiud,mij+1,dr,a,b,decalaj);
    return max(q1,q2);
}
int main()
{
    int i,j,nr1,nr2,Max,q;
    fin>>n>>m;
    for (i=1;i<=n;++i)
        fin>>a[i];
    for (i=1;i<n;++i)
    {
        fin>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1,0,1);
    for (i=1;i<=nr;++i)
    {
        Size[i]=G[i].size();
        for (j=0;j<Size[i]/2;++j)
            swap(G[i][j],G[i][Size[i]-j-1]);
        for (j=0;j<Size[i];++j)
            Poz[G[i][j]]=j+1;
        Start[i]=Start[i-1]+4*Size[i-1];
    }
    for (i=1;i<=n;++i)
        update(1,1,Size[L[i]],Poz[i],a[i],Start[L[i]]);
    for (i=1;i<=m;++i)
    {
        fin>>t>>x>>y;
        if (!t)
            update(1,1,Size[L[x]],Poz[x],y,Start[L[x]]);
        else
        {
            Max=0;
            while (L[x]!=L[y])
            {
                if (Niv[G[L[x]][0]]<Niv[G[L[y]][0]])
                {
                    q=query(1,1,Size[L[y]],1,Poz[y],Start[L[y]]);
                    Max=max(Max,q);
                    y=T[G[L[y]][0]];
                }
                else
                {
                    q=query(1,1,Size[L[x]],1,Poz[x],Start[L[x]]);
                    Max=max(Max,q);
                    x=T[G[L[x]][0]];
                }
            }
            nr1=Poz[x], nr2=Poz[y];
            if (nr1>nr2) swap(nr1,nr2);
            q=query(1,1,Size[L[x]],nr1,nr2,Start[L[x]]);
            Max=max(Max,q);
            fout<<Max<<"\n";
        }
    }
    return 0;
}