Cod sursa(job #2356122)

Utilizator triscacezarTrisca Vicol Cezar triscacezar Data 26 februarie 2019 15:24:51
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.38 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("heavypath.in");
ofstream g("heavypath.out");

int n,test,i,ans,val[100010],tata[100010],weight[100010],bestweight[100010],pos[100010],path[100010],cnt,aint[400010];
vector<int> edges[100010];

void dfs(int poz,int t)
{
    tata[poz]=t;
    weight[poz]=1;
    for(auto it:edges[poz])
        if(it!=t)
        {
            dfs(it,poz);
            weight[poz]+=weight[it];
            if(weight[it]>weight[bestweight[poz]])
                bestweight[poz]=it;
        }
    return ;
}

void heavydfs(int poz,int dad)
{
    pos[poz]=++cnt;
    path[poz]=dad;

    if(bestweight[poz])
    {
        heavydfs(bestweight[poz],dad);
        for(auto it:edges[poz])
            if(it!=tata[poz]&&it!=bestweight[poz])
                heavydfs(it,it);
    }
    return ;
}

void upd(int poz,int l,int r,int wher,int vall)
{
    if(l==r)
    {
        aint[poz]=vall;
        return ;
    }
    int mi=(l+r)/2;
    if(wher<=mi)
        upd(poz*2  ,l   ,mi,wher,vall);
    else
        upd(poz*2+1,mi+1,r ,wher,vall);
    aint[poz]=max(aint[poz*2],aint[poz*2+1]);
    return ;
}

void query(int poz,int l,int r,int lo,int hi)
{
    if(lo<=l&&r<=hi)
    {
        ans=max(ans,aint[poz]);
        return ;
    }
    int mi=(l+r)/2;
    if(lo<=mi)
        query(poz*2  ,l   ,mi,lo,hi);
    if(mi+1<=hi)
        query(poz*2+1,mi+1,r ,lo,hi);
    return;
}

int main()
{
    f>>n>>test;
    for(i=1; i<=n; i++)
        f>>val[i];
    for(i=1; i<n; i++)
    {
        int x,y;
        f>>x>>y;
        edges[x].push_back(y);
        edges[y].push_back(x);
    }
    dfs(1,0);
    heavydfs(1,1);
    for(i=1;i<=n;i++)
        upd(1,1,n,pos[i],val[i]);
    for(;test;test--)
    {
        int t,x,y;
        f>>t>>x>>y;
        if(!t)
            upd(1,1,n,pos[x],y);
        else
        {
            ans=0;
            while(path[x]!=path[y])
                if(pos[x]>pos[y])
                {
                    query(1,1,n,pos[path[x]],pos[x]);
                    x=tata[path[x]];
                }
                else
                {
                    query(1,1,n,pos[path[y]],pos[y]);
                    y=tata[path[y]];
                }
            query(1,1,n,min(pos[x],pos[y]),max(pos[x],pos[y]));
            g<<ans<<'\n';
        }
    }
    return 0;
}