Cod sursa(job #2667882)

Utilizator stefantagaTaga Stefan stefantaga Data 4 noiembrie 2020 00:32:12
Problema Heavy Path Decomposition Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.61 kb
#include <bits/stdc++.h>

using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int viz[100005],nr,nrpath,val[100005],primloc[100005],acum[200005],niv[200005],nrsub[100005],tatic[100005],rmq[20][200005],arb[400005],inceput[100005];
pair <int,int> pozitie[100005];
vector <int> v[100005];
vector <int> paths[200005];
void dfsrad (int x,int tata,int nivel)
{
    int j,ok=0;
    viz[x]=1;
    nr++;
    if (primloc[x]==0)
    {
        primloc[x]=nr;
    }
    acum[nr]=x;
    niv[nr]=nivel;
    for (j=0;j<v[x].size();j++)
    {
        int nod=v[x][j];
        if (viz[nod]==0)
        {
            ok=1;
            tatic[nod]=x;
            dfsrad(nod,x,nivel+1);
            nrsub[x]+=nrsub[nod];
            nr++;
            acum[nr]=x;
            niv[nr]=nivel;
        }
    }
    if (ok==0)
    {
        nrsub[x]=1;
    }
}
int lca (int x,int y)
{
    x=primloc[x];
    y=primloc[y];
    if (x>y)
    {
        swap(x,y);
    }
    if (x==y)
    {
        return acum[x];
    }
    int lg=log2(y-x);
    if (niv[rmq[lg][x]]>niv[rmq[lg][y-(1<<lg)+1]])
    {
        return acum[rmq[lg][y-(1<<lg)+1]];
    }
    return acum[rmq[lg][x]];
}
void dfsheavy(int x)
{
    int j,maxim=0,loc=0;
    viz[x]=1;
    for (j=0;j<v[x].size();j++)
    {
        int nod=v[x][j];
        if (viz[nod]==0&&nrsub[nod]>maxim)
        {
            maxim=nrsub[nod];
            loc=nod;
        }
    }
    if (loc!=0)
    {
        paths[nrpath].push_back(loc);
        inceput[loc]=paths[nrpath][0];
        pozitie[loc]={nrpath,paths[nrpath].size()-1};
        dfsheavy(loc);
    }
}
void update (int st,int dr,int nod,int poz,int val)
{
    if (st==dr)
    {
        arb[nod]=val;
        return;
    }
    int mij=(st+dr)/2;
    if (poz<=mij)
    {
        update(st,mij,2*nod,poz,val);
    }
    else
    {
        update(mij+1,dr,2*nod+1,poz,val);
    }
    arb[nod]=max(arb[2*nod],arb[2*nod+1]);
}
int queryarb (int st,int dr,int nod ,int ua,int ub)
{
    if (ua<=st&&dr<=ub)
    {
        return arb[nod];
    }
    int mij=(st+dr)/2;
    int r1=INT_MIN,r2=INT_MIN;
    if (ua<=mij)
    {
        r1=queryarb(st,mij,2*nod,ua,ub);
    }
    if (mij<ub)
    {
        r2=queryarb(mij+1,dr,2*nod+1,ua,ub);
    }
    return max(r1,r2);
}
int n,m,i,x,y,lg,putere,j,tip;
int query (int st,int dr)
{
    int copie,solutie,indice,pozitieelem;
    solutie=0;
    copie=st;
    while (copie!=dr)
    {
        pozitieelem=pozitie[copie].second;
        indice=pozitie[copie].first;
        if (pozitie[dr].first==pozitie[copie].first)
        {
            solutie=max(solutie,queryarb(1,n,1,pozitie[dr].second,pozitie[copie].second));
            copie=dr;
        }
        else
        {
           solutie=max(solutie,queryarb(1,n,1,pozitie[paths[indice][0]].second,pozitie[copie].second));
           copie=paths[pozitie[copie].first][0];
        if (copie!=dr)
        {
            copie=tatic[copie];
        }
        }
    }
    solutie=max(solutie,val[dr]);
    return solutie;
}
int pozitie2;
int main()
{
    f>>n>>m;
    for (i=1;i<=n;i++)
    {
        f>>val[i];
    }
    for (i=1;i<=n-1;i++)
    {
        f>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfsrad(1,0,1);
    for (i=1;i<=nr;i++)
    {
        rmq[0][i]=i;
    }
    lg=log2(nr);
    for (i=1;i<=lg;i++)
    {
        putere=(1<<(i-1));
        for (j=1;j<=nr-putere+1;j++)
        {
            if (niv[rmq[i-1][j]]>niv[rmq[i-1][j+putere]])
            {
                rmq[i][j]=rmq[i-1][j+putere];
            }
            else
            {
                rmq[i][j]=rmq[i-1][j];
            }
        }
    }
    memset(viz,0,sizeof(viz));
    for (i=1;i<=n;i++)
    {
        if (viz[i]==0)
        {
            nrpath++;
            paths[nrpath].push_back(i);
            pozitie[i]={nrpath,0};
            dfsheavy(i);
        }
    }
    pozitie2=0;
    for (i=1;i<=nrpath;i++)
    {
        for (j=0;j<paths[i].size();j++)
        {
            pozitie2++;
            update(1,n,1,pozitie2,val[paths[i][j]]);
            pozitie[paths[i][j]].second=pozitie2;
        }
    }
    for (m;m--;)
    {

        f>>tip>>x>>y;
        if (tip==1)
        {
            int lowestca=lca(x,y);
            g<<max(query(x,lowestca),query(y,lowestca))<<'\n';
        }
        else
        {
            /// indice =pozitie[x].first;
            /// pozitie =pozitie[x].second;
            update(1,n,1,pozitie[x].second,y);
            val[x]=y;
        }
    }
    return 0;
}