Cod sursa(job #1691240)

Utilizator ArchazeyBaltatu Andrei-Mircea Archazey Data 17 aprilie 2016 16:53:38
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.77 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

const int NMAX=100005;

int n,m,len,a[NMAX],sub[NMAX],fat[NMAX],niv[NMAX];
int poz[NMAX],path[NMAX];
vector<int>v[NMAX];
vector<int>aint[NMAX],see[NMAX];

void Dfs(int x,int f)
{
    sub[x]=1;niv[x]=niv[f]+1;
    int node=0;
    for (auto it : v[x])
        if (it!=f)
        {
            Dfs(it,x);
            sub[x]+=sub[it];
            if (sub[it]>sub[node]) node=it;
        }
    if (!node)
    {
        len++;
        poz[x]=1;path[x]=len;
        see[len].push_back(x);
    }
    else
    {
        poz[x]=poz[node]+1;
        path[x]=path[node];
        see[path[x]].push_back(x);
    }
    for (auto it : v[x])
        if (it!=node && it!=f)
            fat[path[it]]=x;
}

void Update(int nod,int st,int dr,int poz,int val,int in)
{
    if (st==dr) aint[in][nod]=val;
    else
    {
        int mij=(st+dr)>>1;

        if (poz<=mij) Update(2*nod,st,mij,poz,val,in);
        if (poz>mij) Update(2*nod+1,mij+1,dr,poz,val,in);

        aint[in][nod]=max(aint[in][2*nod],aint[in][2*nod+1]);
    }
}

int Query(int nod,int st,int dr,int c,int d,int in)
{
    if (c<=st && dr<=d) return aint[in][nod];
    else
    {
        int mij=(st+dr)>>1,rez=0;

        if (c<=mij) rez=max(rez,Query(2*nod,st,mij,c,d,in));
        if (d>mij) rez=max(rez,Query(2*nod+1,mij+1,dr,c,d,in));

        return rez;
    }
}

int main()
{
    int i,x,y,op,sol;
    fin>>n>>m;
    for (i=1;i<=n;i++) fin>>a[i];
    for (i=1;i<n;i++)
    {
        fin>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }

    Dfs(1,0);

    for (i=1;i<=len;i++)
    {
        aint[i].resize(see[i].size()*4 + 5,0);
        for (auto it : see[i])
            Update(1,1,see[i].size(),poz[it],a[it],i);
    }

    for (i=1;i<=m;i++)
    {
        fin>>op>>x>>y;
        if (op==0) Update(1,1,see[path[x]].size(),poz[x],y,path[x]);
        if (op==1)
        {
            sol=0;
            while (path[x]!=path[y])
            {
                if (niv[fat[path[x]]]>=niv[fat[path[y]]])//urc cu x
                {
                    sol=max(sol,Query(1,1,see[path[x]].size(),poz[x],see[path[x]].size(),path[x]));
                    x=fat[path[x]];
                }
                else//urc cu y
                {
                    sol=max(sol,Query(1,1,see[path[y]].size(),poz[y],see[path[y]].size(),path[y]));
                    y=fat[path[y]];
                }
            }
            //ambii sunt pe acelasi lant,al lca-ului
            if (poz[x]>poz[y]) swap(x,y);
            sol=max(sol,Query(1,1,see[path[x]].size(),poz[x],poz[y],path[x]));

            fout<<sol<<"\n";
        }
    }

    return 0;
}