Cod sursa(job #3223162)

Utilizator Cazacu2006RazvanRazvan Cazacu Cazacu2006Razvan Data 12 aprilie 2024 15:46:30
Problema Heavy Path Decomposition Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.32 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int n,m,v[105001],q,fr[105001],fs[105001],viz[105001],rep[105001],val,k,indp,nrp[105001],first[105001],ult[105001],aint[405001],nodi[105001],nr,niv[105001],t[105001],ch2;
vector <int> A[105001];
void dfs(int nod,int tata)
{
    niv[nod]=niv[tata]+1;
    if(A[nod].size()==1 && nod!=1)
    {

        k++;
        fr[nod]=k;
        nrp[k]=1;
        nr++;
        return;

    }
    int maxim=0,ind=0;
    for(auto i:A[nod])
    {
        if(i!=tata)
        {
            dfs(i,nod);

            if(maxim<nrp[fr[i]])
            {
                maxim=nrp[fr[i]];
                ind=fr[i];
            }

        }
    }
    for(auto i:A[nod])
    {
        if(i!=tata)
        {
            if(fr[i]!=ind)
            {
                nrp[ind]+=nrp[fr[i]];
                t[fr[i]]=nod;
            }

        }
    }
    nrp[ind]++;
    fr[nod]=ind;
}
void update(int nod,int st,int dr,int x,int valo)
{
    if(st==dr)
    {

        aint[nod]=valo;

    }
    else if(st<dr)
    {
        int mid=(st+dr)/2;
        if(x>mid)
            update(nod*2+1,mid+1,dr,x,valo);
        else
            update(nod*2,st,mid,x,valo);
        aint[nod]=max(aint[nod*2],aint[nod*2+1]);
    }

}
void dfs2(int nod,int tata)
{
     viz[nod]=1;
    indp++;
    rep[nod]=indp;
    if(A[nod].size()==1 && nod!=1){
        first[fr[nod]]=indp;
        fs[fr[nod]]=nod;
    }
    int ch=0;
    for(auto i:A[nod])
    {
        if(i!=tata)
        {

            if(fr[nod]==fr[i])
            {
                ch++;
                dfs2(i,nod);

            }

        }
    }
    if(ch==0)
    {
        ult[fr[nod]]=indp;
    }

    update(1,1,n,rep[nod],v[nod]);
}
void query(int nod,int st,int dr,int x,int y)
{
    if(x<=st && dr<=y)
    {
        val=max(val,aint[nod]);
    }
    else if(st<dr)
    {
        int mid=(st+dr)/2;
        if(y>mid)
            query(nod*2+1,mid+1,dr,x,y);
        if(x<=mid)
            query(nod*2,st,mid,x,y);
    }
}
int rezolv(int x,int y)
{
    int maxim=0;
    while(1)
    {

        if(niv[ult[fr[x]]]<niv[ult[fr[y]]])
                swap(x,y);
        if(t[fr[x]]==0)
            swap(x,y);
        val=0;
        if(fr[x]==fr[y])
        {
            if(rep[x]<rep[y])
                swap(x,y);

            query(1,1,n,rep[y],rep[x]);
            maxim=max(maxim,val);
            return maxim;
        }

        query(1,1,n,rep[x],ult[fr[x]]);
        maxim=max(maxim,val);
        x=t[fr[x]];
        if(fr[x]==0 || fr[y]==0)
            fout<<1<<" ";


    }

}
int main()
{
    fin>>n>>m;
    for(int i=1;i<=n;i++)
        fin>>v[i];
    for(int i=1;i<n;i++)
    {
        int x,y;
        fin>>x>>y;
        A[x].push_back(y);
        A[y].push_back(x);
    }
    dfs(1,0);
    for(int i=2;i<=n;i++)
    {
        if(viz[i]==0 && A[i].size()==1){
            dfs2(i,0);
        }
    }
    for(int i=1;i<=m;i++)
    {
        int t,x,y;
        fin>>t>>x>>y;
        if(t==0)
        {
            v[x]=y;
            update(1,1,n,rep[x],y);
        }
        else
        {

             fout<<rezolv(x,y)<<"\n";
        }
    }
    return 0;
}