Cod sursa(job #3237502)

Utilizator Anul2024Anul2024 Anul2024 Data 9 iulie 2024 14:08:52
Problema Heavy Path Decomposition Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.23 kb
#include <cstdio>
#include <vector>
#define dimbuff 1000000
using namespace std;
FILE *fin=fopen ("heavypath.in","r");
FILE *fout=fopen ("heavypath.out","w");
int n,q,i,x,y,sol,ch,nrr;
int niv,st,dr,nr,nod,val;
int tata[100001],poz[100001],nivel[100001];
int lg[100001],dp[100001],nivinit[100001],t[100001],lant[100001],valnr[100001];
vector <int> v[100001],noduri[100001];
char buff[dimbuff+5];
int pp;
int numar()
{
    int val=0;
    while (!(buff[pp]>='0'&&buff[pp]<='9'))
    {
        pp++;
        if (pp==dimbuff)
        {
            fread(buff,1,dimbuff,fin);
            pp=0;
        }
    }
    while (buff[pp]>='0'&&buff[pp]<='9')
    {
        val=val*10+buff[pp]-'0';
        pp++;
        if (pp==dimbuff)
        {
            fread (buff,1,dimbuff,fin);
            pp=0;
        }
    }
    return val;
}
class segtree
{
private:
    vector <int> v;
public:
    void marime (int n)
    {
        v.resize (4*n+1,0);
    }
    void build (int nod,int st,int dr)
    {
        if (st==dr)
            v[nod]=valnr[st];
        else
        {
            int mij=(st+dr)/2;
            build (2*nod,st,mij);
            build (2*nod+1,mij+1,dr);
            v[nod]=max (v[2*nod],v[2*nod+1]);
        }
    }
    void update (int nod,int st,int dr,int poz,int val)
    {
        if (st==dr)
            v[nod]=val;
        else
        {
            int mij=(st+dr)/2;
            if (poz<=mij)
                update (2*nod,st,mij,poz,val);
            else
                update (2*nod+1,mij+1,dr,poz,val);
            v[nod]=max (v[2*nod],v[2*nod+1]);
        }
    }
    void query (int nod,int st,int dr,int a,int b,int &sol)
    {
        if (st>=a&&dr<=b)
            sol=max (sol,v[nod]);
        else
        {
            int mij=(st+dr)/2;
            if (a<=mij)
                query (2*nod,st,mij,a,b,sol);
            if (b>=mij+1)
                query (2*nod+1,mij+1,dr,a,b,sol);
        }
    }
};
segtree aint[100001];
void dfs (int nod,int t,int niv)
{
    nivinit[nod]=niv;
    for (int i=0; i<v[nod].size (); i++)
    {
        int vecin=v[nod][i];
        if (vecin!=t)
        {
            dfs (vecin,nod,niv+1);
            if (dp[vecin]>dp[nod])
            {
                dp[nod]=dp[vecin];
                poz[nod]=vecin;
            }
        }
    }
    dp[nod]++;
}
void dfs_lant (int nod,int tt)
{
    nrr++;
    int nr=nrr;
    t[nr]=nod;
    int niv=0;
    while (nod!=0)
    {
        noduri[nr].push_back (nod);
        for (int i=0; i<v[nod].size (); i++)
        {
            int vecin=v[nod][i];
            if (vecin!=tt&&vecin!=poz[nod])
                dfs_lant (vecin,nod);
        }
        niv++;
        lant[nod]=nr;
        nivel[nod]=niv;
        tata[nod]=tt;
        tt=nod;
        nod=poz[nod];
    }
    aint[nr].marime (niv);
    lg[nr]=niv;
    for (int i=0; i<noduri[nr].size (); i++)
        aint[nr].update (1,1,niv,i+1,valnr[noduri[nr][i]]);
}
int main ()
{
    n=numar ();
    q=numar ();
    for (i=1; i<=n; i++)
        valnr[i]=numar ();
    for (i=1; i<n; i++)
    {
        x=numar ();
        y=numar ();
        v[x].push_back (y);
        v[y].push_back (x);
    }
    dfs (1,0,1);
    dfs_lant (1,0);
    while (q--)
    {
        ch=numar ();
        if (ch==0)
        {
            nod=numar ();
            val=numar ();
            aint[lant[nod]].update (1,1,lg[lant[nod]],nivel[nod],val);
        }
        else
        {
            x=numar ();
            y=numar ();
            sol=0;
            while (lant[x]!=lant[y])
            {
                if (nivinit[t[lant[x]]]>=nivinit[t[lant[y]]])
                {
                    aint[lant[x]].query (1,1,lg[lant[x]],1,nivel[x],sol);
                    x=tata[t[lant[x]]];
                }
                else
                {
                    aint[lant[y]].query (1,1,lg[lant[y]],1,nivel[y],sol);
                    y=tata[t[lant[y]]];
                }
            }
            st=min (nivel[x],nivel[y]);
            dr=max (nivel[x],nivel[y]);
            aint[lant[x]].query (1,1,lg[lant[x]],st,dr,sol);
            fprintf (fout,"%d\n",sol);
        }
    }
    return 0;
}