Cod sursa(job #3274428)

Utilizator AlexandruTigauTigau Alexandru AlexandruTigau Data 6 februarie 2025 19:07:40
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.66 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
#define N 100005
int val[N],parent[N],chain[N],subtree[N],sizee[N],nr,level[N],position[N],descendant[N];
vector<int> v[N],chains[N],aint[N];
void dfs(int x)
{
    level[x]=level[parent[x]]+1;
    int maxx=-1;
    for(auto i:v[x])
        if(i!=parent[x])
    {
        parent[i]=x;
        dfs(i);
        subtree[x]+=subtree[i];
        if(subtree[i]>maxx)
            maxx=subtree[i], descendant[x]=i;
    }
}
void dfs2(int x)
{
    for(auto i:v[x])
        if(i!=parent[x])
    {
        if(descendant[x]==i)
        {
            chains[chain[x]].push_back(i);
            chain[i]=chain[x];
            position[i]=position[x]+1;
        }
        else
        {
            chains[++nr].push_back(i);
            chain[i]=nr;
        }
        dfs2(i);
    }
}
void update(int ind, int nod, int st, int dr, int poz)
{
    if(st>poz||dr<poz)
        return;
    if(st==dr)
    {
        aint[ind][nod]=val[chains[ind][poz-1]];
        return;
    }
    int mijl=(st+dr)/2;
    update(ind,nod*2,st,mijl,poz);
    update(ind,nod*2+1,mijl+1,dr,poz);
    aint[ind][nod]=max(aint[ind][nod*2],aint[ind][nod*2+1]);
}
int query(int ind, int nod, int st, int dr, int in, int sf)
{
    if(in>dr||sf<st)
        return -1;
    if(in<=st&&dr<=sf)
        return aint[ind][nod];
    int mijl=(st+dr)/2;
    return max(query(ind,nod*2,st,mijl,in,sf),query(ind,nod*2+1,mijl+1,dr,in,sf));
}
int main()
{
    int n,m;
    f>>n>>m;
    for(int i=1;i<=n;i++)
    {
        f>>val[i];
        subtree[i]=1;
    }
    for(int i=1;i<n;i++)
    {
        int a,b;
        f>>a>>b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    chain[1]=++nr;
    chains[nr].push_back(1);
    dfs(1);
    dfs2(1);
    for(int i=1;i<=nr;i++)
    {
        sizee[i]=chains[i].size();
        aint[i].resize(4*sizee[i]);
        for(int j=0;j<sizee[i];j++)
            update(i,1,1,sizee[i],j+1);
    }
    while(m--)
    {
        int t,x,y;
        f>>t>>x>>y;
        if(t==0)
        {
            val[x]=y;
            update(chain[x],1,1,sizee[chain[x]],position[x]+1);
        }
        else
        {
            int maxx=-1;
            while(chain[x]!=chain[y])
            {
                if(level[chains[chain[x]][0]]<level[chains[chain[y]][0]])
                    swap(x,y);
                maxx=max(maxx,query(chain[x],1,1,sizee[chain[x]],1,position[x]+1));
                x=parent[chains[chain[x]][0]];
            }
            if(position[x]>position[y])
                swap(x,y);
            g<<max(maxx,query(chain[x],1,1,sizee[chain[x]],position[x]+1,position[y]+1))<<'\n';
        }
    }
    return 0;
}