Cod sursa(job #2919013)

Utilizator mihneazzzMacovei Daniel mihneazzz Data 14 august 2022 19:54:25
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.86 kb
#include <bits/stdc++.h>
#define N 100005
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int n,m,a[N],cnt[N],niv[N],aint[4*N];
int lant[N],ldim[N],nL,ltata[N],lniv[N],lpoz[N];
bool viz[N];
vector<int>g[N],L[N];
void Citire()
{
    int i,x,y;
    fin>>n>>m;
    for(i=1;i<=n;i++) fin>>a[i];
    for(i=1;i<n;i++) fin>>x>>y,g[x].push_back(y),g[y].push_back(x);
}
void DFS(int nod)
{
    viz[nod]=1;
    cnt[nod]=1;
    bool frunza=1;
    int veriga=0;
    for(auto x:g[nod])
        if(!viz[x])
    {
        frunza=0;
        niv[x]=niv[nod]+1;
        DFS(x);
        cnt[nod]+=cnt[x];
        if(!veriga) veriga=x;
        else if(cnt[veriga]<cnt[x]) veriga=x;
    }
    if(frunza)
    {
        lant[nod]=++nL;
        ldim[nL]=1;
        L[nL].push_back(nod);
        return;
    }
    lant[nod]=lant[veriga];
    ++ldim[lant[nod]];
    L[lant[nod]].push_back(nod);
    for(auto x:g[nod])
        if(x!=veriga && niv[x]>=niv[nod])
          ltata[lant[x]]=nod,lniv[lant[x]]=niv[nod];
}
void build(int nod,int st,int dr,int decalaj,int lant)
{
    if(st==dr) {aint[nod+decalaj]=a[L[lant][st-1]];return;}
    int mij=(st+dr)/2;
    build(2*nod,st,mij,decalaj,lant);
    build(2*nod+1,mij+1,dr,decalaj,lant);
    aint[nod+decalaj]=max(aint[2*nod+decalaj],aint[2*nod+1+decalaj]);
}
void make_paths()
{
    niv[1]=1;
    DFS(1);
    for(int i=1;i<=nL;i++)
    {
        reverse(L[i].begin(),L[i].end());
        lpoz[i]=lpoz[i-1]+4*ldim[i-1];
        build(1,1,ldim[i],lpoz[i],i);
    }
}
void Update(int nod,int st,int dr,int poz,int val,int decalaj)
{
    if(st==dr) {aint[nod+decalaj]=val;return;}
    int mij=(st+dr)>>1;
    if(poz<=mij) Update(2*nod,st,mij,poz,val,decalaj);
    else Update(2*nod+1,mij+1,dr,poz,val,decalaj);
    aint[nod+decalaj]=max(aint[2*nod+decalaj],aint[2*nod+1+decalaj]);
}
int Query(int nod,int st,int dr,int x,int y,int decalaj)
{
    if(x<=st && dr<=y) return aint[nod+decalaj];
    int mij=(st+dr)>>1,M=0;
    if(x<=mij) M=max(M,Query(2*nod,st,mij,x,y,decalaj));
    if(y>mij) M=max(M,Query(2*nod+1,mij+1,dr,x,y,decalaj));
    return M;
}
void HPD()
{
    bool op;
    int x,y;
    while(m--)
    {
        fin>>op>>x>>y;
        if(!op) Update(1,1,ldim[lant[x]],niv[x]-lniv[lant[x]],y,lpoz[lant[x]]);
        else
        {
            int M=0;
            while(lant[x]!=lant[y])
            {
                if(lniv[lant[x]]<lniv[lant[y]]) swap(x,y);
                M=max(M,Query(1,1,ldim[lant[x]],1,niv[x]-lniv[lant[x]],lpoz[lant[x]]));
                x=ltata[lant[x]];
            }
            if(niv[x]>niv[y]) swap(x,y);
            M=max(M,Query(1,1,ldim[lant[x]],niv[x]-lniv[lant[x]],niv[y]-lniv[lant[x]],lpoz[lant[x]]));
            fout<<M<<"\n";
        }
    }
}
int main()
{
    Citire();
    make_paths();
    HPD();
    return 0;
}