Cod sursa(job #2145889)

Utilizator CodrinsahCotarlan Codrin Codrinsah Data 27 februarie 2018 17:51:55
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.67 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fi ("heavypath.in");
ofstream fo ("heavypath.out");
vector<int> v[100005],lant[100005];
int n,m,lvl,lg,nrlant,sol;
int weight[100005],val[100005],viz[100005],nivel[100005],t[100005];
int Ltata[100005],Lnivel[100005],a[400005],Lpoz[100005],valmax[100005],pozinlant[100005],pozina[100005];
int lantnod[100005];
int findWeight(int nod)
{
    lvl++;
    viz[nod]=1;
    if (v[nod].size()==0)
    {
        weight[nod]=1;
        return weight[nod];
    }
    for (int i=0;i<v[nod].size();i++)
        if (!viz[v[nod][i]])
        {
            t[v[nod][i]]=nod;
            weight[nod]=weight[nod]+findWeight(v[nod][i]);
        }
    weight[nod]++;
    lvl--;
    return weight[nod];
}
void genLant(int nod)
{
    lg++;
    lant[nrlant].push_back(nod);
    pozinlant[nod]=lg;
    lantnod[nod]=nrlant;
    if (lg==1) valmax[nod]=val[nod];
    else valmax[nod]=max(val[nod],val[lant[nrlant][lg-2]]);
    if (v[nod].size()==1 and nod!=1)
    {
        Ltata[nrlant]=t[lant[nrlant][0]];
        Lnivel[nrlant]=Lnivel[lantnod[Ltata[nrlant]]]+1;
        lg=0;
        nrlant++;
        return;
    }
    for (int i=0;i<v[nod].size();i++)
        if (t[v[nod][i]]==nod) genLant(v[nod][i]);
}
void generare(int nod,int st,int dr,int delay,int nl)
{
    int mij;
    if (st<dr)
    {
        mij=(st+dr)/2;
        generare(2*nod,st,mij,delay,nl);
        generare(2*nod+1,mij+1,dr,delay,nl);
        a[nod+delay]=max(a[2*nod+delay],a[2*nod+1+delay]);
    }
    else
    {
        a[nod+delay]=val[lant[nl][st-1]];
        pozina[lant[nl][st-1]]=nod;
    }
}
void update(int nod,int delay,int nr)
{
    if (nod<=1) return;
    if (pozina[nr]==nod) a[nod+delay]=val[nr];
    int nextnod=nod/2;
    a[nextnod+delay]=max(a[2*nextnod+delay],a[2*nextnod+1+delay]);
    update(nextnod,delay,nr);
}
void solve(int nod,int st,int dr,int delay,int nl,int poz1,int poz2)
{
    int mij=(st+dr)/2;
    if (dr<poz1) return;
    if (st>poz2) return;
    if (st>=poz1 and dr<=poz2) {sol=max(sol,a[nod+delay]);return;}
    if (st<=mij) solve(2*nod,st,mij,delay,nl,poz1,poz2);
    if (dr>mij) solve(2*nod+1,mij+1,dr,delay,nl,poz1,poz2);
}
int main()
{
    fi>>n>>m;
    for (int i=1;i<=n;i++) fi>>val[i];
    for (int i=1;i<=n-1;i++)
    {
        int nod1,nod2;
        fi>>nod1>>nod2;
        v[nod1].push_back(nod2);
        v[nod2].push_back(nod1);
    }
    lvl=-1;
    weight[1]=findWeight(1);
    nrlant=1;
    genLant(1);
    nrlant--;
    for (int i=1;i<=nrlant;i++)
    {
        if (i>1) Lpoz[i]=Lpoz[i-1]+4*lant[i-1].size();
        generare(1,1,lant[i].size(),Lpoz[i],i);
    }
    for (int i=1;i<=m;i++)
    {
        int t,k,x,y;
        sol=0;
        fi>>t>>x>>y;
        if (t==0)
        {
            val[x]=y;
            k=lantnod[x];
            update(pozina[x],Lpoz[k],x);
//            generare(1,1,lant[k].size(),Lpoz[k],k);
//            for (int j=1;j<=17;j++) fo<<a[j]<<' ';
//            fo<<'\n';
        }
        if (t==1)
        {
            while (lantnod[x]!=lantnod[y])
            {
                if (Lnivel[lantnod[x]]<Lnivel[lantnod[y]]) swap (x,y);
                k=lantnod[x];
                solve(1,1,lant[k].size(),Lpoz[k],k,1,pozinlant[x]);
                x=Ltata[k];
            }
            k=lantnod[x];
            if (pozinlant[x]>pozinlant[y]) swap (x,y);
            solve (1,1,lant[k].size(),Lpoz[k],k,pozinlant[x],pozinlant[y]);
            fo<<sol<<'\n';
        }
    }
//    for (int i=1;i<=nrlant;i++)
//    {
//        for (int j=0;j<lant[i].size();j++) fo<<lant[i][j]<<' ';
//        fo<<'\n';
//    }
    return 0;
}