Cod sursa(job #2363882)

Utilizator dacianouaPapadia Mortala dacianoua Data 3 martie 2019 18:37:26
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.42 kb
#include <iostream>
#include <fstream>
#include <vector>
#define nmax 100000
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int n,m,seg[(nmax<<2)+5],dad[nmax+5],link[nmax+5],s[nmax+5],level[nmax+5],poz[nmax+5],cnt,v[nmax+5];
vector<int> graf[nmax+5];
int maxv(int x,int y)
{
    return x>y?x:y;
}
int dfs(int tata,int nod)
{
    s[nod]=1;
    dad[nod]=tata;
    if(tata==-1)
        level[nod]=1;
    else
        level[nod]=level[tata]+1;
    for(auto fiu:graf[nod])
        if(fiu!=tata)
        s[nod]+=dfs(nod,fiu);
    return s[nod];
}
void make_links(int tata,int nod)
{
    int mx=0;
    poz[nod]=++cnt;
    for(auto fiu:graf[nod])
        if(fiu!=tata && s[fiu]>s[mx])
            mx=fiu;
    if(mx)
    {
        link[mx]=link[nod];
        make_links(nod,mx);
    }
    for(auto fiu:graf[nod])
        if(fiu!=tata && fiu!=mx)
        {
            link[fiu]=fiu;
            make_links(nod,fiu);
        }
}
void update(int poz,int val)
{
    poz+=n;
    seg[poz]=val;
    poz>>=1;
    while(poz>1)
    {
        seg[poz]=maxv(seg[poz<<1],seg[(poz<<1)+1]);
        poz>>=1;
    }
}
int query(int st,int dr)
{
    st+=n;
    dr+=n+1;
    int sol=0;
    while(st!=dr)
    {
        if(st%2)
           sol=maxv(sol,seg[st++]);
        if(dr%2)
            sol=maxv(sol,seg[--dr]);
        st>>=1;
        dr>>=1;
    }
    return sol;
}
int main()
{
    fin>>n>>m;
    int t,x,y,sol;
    for(int i=1;i<=n;i++)
        fin>>v[i];
    for(int i=1;i<=n-1;i++)
    {
        fin>>x>>y;
        graf[x].push_back(y);
        graf[y].push_back(x);
    }
    dfs(-1,1);
    link[1]=1;
    make_links(-1,1);
    for(int i=1;i<=n;i++)
        update(poz[i],v[i]);
    for(int i=1;i<=m;i++)
    {
        fin>>t;
        switch(t)
        {
        case 0:
            fin>>x>>y;
            update(poz[x],y);
            break;
        case 1:
            sol=0;
            fin>>x>>y;

            while(link[x]!=link[y])
            {
                if(level[link[x]] < level[link[y]])
                    x^=y,y^=x,x^=y;
                sol=maxv(sol,query(poz[link[x]],poz[x]));
                x=dad[link[x]];

            }
            if(level[x]<level[y])
                x^=y,y^=x,x^=y;
            sol=maxv(sol,query(poz[y],poz[x]));
            fout<<sol<<"\n";
            break;
        }
    }
    return 0;
}