Cod sursa(job #3031786)

Utilizator hhhhhhhAndrei Boaca hhhhhhh Data 20 martie 2023 19:45:29
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.52 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int n,m,val[100005],par[100005],nr[100005],isheavy[100005],nrpath,what[100005],niv[100005];
int pathpar[100005],poz[100005],lg[100005];
int in[100005],out[100005],timp;
int **arb;
vector<vector<int>> muchii;
vector<vector<int>> path;
void update(int index,int nod,int st,int dr,int poz,int val)
{
    if(st==dr)
    {
        arb[index][nod]=val;
        return;
    }
    int mij=(st+dr)/2;
    if(poz<=mij)
        update(index,nod*2,st,mij,poz,val);
    else
        update(index,nod*2+1,mij+1,dr,poz,val);
    arb[index][nod]=max(arb[index][nod*2],arb[index][nod*2+1]);
}
int query(int index,int nod,int st,int dr,int a,int b)
{
    if(st>=a&&dr<=b)
        return arb[index][nod];
    int mij=(st+dr)/2;
    int rez=0;
    if(a<=mij)
        rez=max(rez,query(index,nod*2,st,mij,a,b));
    if(b>mij)
        rez=max(rez,query(index,nod*2+1,mij+1,dr,a,b));
    return rez;
}
void dfs(int nod)
{
    timp++;
    in[nod]=timp;
    nr[nod]=1;
    if(niv[nod]==0)
        niv[nod]=1;
    int best=0;
    int maxim=0;
    for(auto i:muchii[nod])
        if(i!=par[nod])
        {
            niv[i]=niv[nod]+1;
            par[i]=nod;
            dfs(i);
            nr[nod]+=nr[i];
            if(maxim<nr[i])
            {
                maxim=nr[i];
                best=i;
            }
        }
    if(best!=0)
        isheavy[best]=1;
    timp++;
    out[nod]=timp;
}
int getmax(int x,int y)
{
    if(what[x]==what[y])
        return query(what[y],1,1,lg[what[y]],min(poz[x],poz[y]),max(poz[x],poz[y]));
    if(niv[path[what[x]][lg[what[x]]-1]]>=niv[path[what[y]][lg[what[y]]-1]])
        return max(getmax(x,path[what[x]][lg[what[x]]-1]),getmax(pathpar[what[x]],y));
    else
    {
        swap(x,y);
        return max(getmax(x,path[what[x]][lg[what[x]]-1]),getmax(pathpar[what[x]],y));
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    fin.tie(0);
    fout.tie(0);
    fin>>n>>m;
    for(int i=1;i<=n;i++)
        fin>>val[i];
    muchii.resize(n+1);
    for(int i=1;i<n;i++)
    {
        int a,b;
        fin>>a>>b;
        muchii[a].push_back(b);
        muchii[b].push_back(a);
    }
    dfs(1);
    for(int i=1;i<=n;i++)
    {
        bool found=0;
        int nod=i;
        for(auto j:muchii[nod])
            if(j!=par[nod])
                if(isheavy[j]==1)
                    found=1;
        if(found==0)
        {
            nrpath++;
            path.resize(nrpath+1);
            path[nrpath].push_back(nod);
            what[nod]=nrpath;
            while(isheavy[nod])
            {
                nod=par[nod];
                what[nod]=nrpath;
                path[nrpath].push_back(nod);
            }
        }
    }
    arb=new int *[nrpath+1];
    //assert(nrpath<=30);
    for(int i=1;i<=nrpath;i++)
    {
        //reverse(path[i].begin(),path[i].end());
        lg[i]=path[i].size();
        arb[i]=new int [4*lg[i]+1];
        for(int j=0;j<path[i].size();j++)
        {
            poz[path[i][j]]=j+1;
            pathpar[i]=par[path[i][j]];
        }
    }
    for(int i=1;i<=n;i++)
        update(what[i],1,1,lg[what[i]],poz[i],val[i]);
    while(m--)
    {
        int tip,x,y;
        fin>>tip>>x>>y;
        if(tip==0)
            update(what[x],1,1,lg[what[x]],poz[x],y);
        else
        {
            int rez=getmax(x,y);
            fout<<rez<<'\n';
        }
    }
    return 0;
}