Cod sursa(job #3237800)

Utilizator Anul2024Anul2024 Anul2024 Data 13 iulie 2024 11:48:05
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.72 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
vector <int> v[100001],noduri_lant[100001];
int n,q,i,j,x,y,ch,sol,nr,st,dr,nod,val,valnr[100001];
int nivinit[100001],t[100001],lant[100001],lg_lant[100001],dp[100001],nivel[100001];
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[noduri_lant[i][st-1]];
        else
        {
            int mij=(st+dr)/2;
            build ((1<<nod),st,mij);
            build ((1<<nod)+1,mij+1,dr);
            v[nod]=max (v[(1<<nod)],v[(1<<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 ((1<<nod),st,mij,poz,val);
            else
                update ((1<<nod)+1,mij+1,dr,poz,val);
            v[nod]=max (v[(1<<nod)],v[(1<<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 ((1<<nod),st,mij,a,b,sol);
            if (b>=mij+1)
                query ((1<<nod)+1,mij+1,dr,a,b,sol);
        }
    }
};
segtree aint[100001];
void dfs (int nod,int tt,int niv)
{
    int poz=0;
    for (int i=0; i<v[nod].size (); i++)
    {
        int vecin=v[nod][i];
        if (vecin!=tt)
        {
            dfs (vecin,nod,niv+1);
            if (dp[vecin]>dp[nod])
            {
                dp[nod]=dp[vecin];
                poz=vecin;
            }
        }
    }
    dp[nod]++;
    nivinit[nod]=niv;
    if (poz==0)
    {
        nr++;
        lant[nod]=nr;
        noduri_lant[lant[nod]].push_back (nod);
    }
    else
    {
        lant[nod]=lant[poz];
        noduri_lant[lant[nod]].push_back (nod);
    }
    for (int i=0; i<v[nod].size (); i++)
    {
        int vecin=v[nod][i];
        if (vecin!=tt&&vecin!=poz)
            t[lant[vecin]]=nod;
    }
}
int main ()
{
    fin>>n>>q;
    for (i=1; i<=n; i++)
        fin>>valnr[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++)
    {
        lg_lant[i]=noduri_lant[i].size ();
        aint[i].marime (lg_lant[i]);
        reverse (noduri_lant[i].begin (),noduri_lant[i].end ());
        aint[i].build (1,1,lg_lant[i]);
        for (j=0; j<noduri_lant[i].size (); j++)
            nivel[noduri_lant[i][j]]=j+1;
    }
    while (q--)
    {
        fin>>ch;
        if (ch==0)
        {
            fin>>nod>>val;
            aint[lant[nod]].update (1,1,lg_lant[lant[nod]],nivel[nod],val);
        }
        else
        {
            fin>>x>>y;
            sol=0;
            while (lant[x]!=lant[y])
            {
                if (nivinit[t[lant[x]]]>=nivinit[t[lant[y]]])
                {
                    aint[lant[x]].query (1,1,lg_lant[lant[x]],1,nivel[x],sol);
                    x=t[lant[x]];
                }
                else
                {
                    aint[lant[y]].query (1,1,lg_lant[lant[y]],1,nivel[y],sol);
                    y=t[lant[y]];
                }
            }
            st=min (nivel[x],nivel[y]);
            dr=max (nivel[x],nivel[y]);
            aint[lant[x]].query (1,1,lg_lant[lant[x]],st,dr,sol);
            fout<<sol<<"\n";
        }
    }
    return 0;
}