Cod sursa(job #1412581)

Utilizator misinoonisim necula misino Data 1 aprilie 2015 12:56:48
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.1 kb
#include<fstream>
#include<algorithm>
#include<vector>
#define pb push_back
#define N 100100
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int n,m,i,j,l1,l2,sol,tip,x,y,poz[N],niv[N],t[N],tata[N],val[N],viz[N],nrnod[N],lant[N],nrl;
vector<int>v[N],aint[N],l[N];
inline void dfs(int x){
    viz[x]=1;
    nrnod[x]=1;
    int pozm=-1;
    for(vector<int>::iterator it=v[x].begin();it!=v[x].end();++it)
    if(!viz[*it])
    {
        dfs(*it);
        nrnod[x]+=nrnod[*it];
        if(pozm==-1||nrnod[*it]>nrnod[pozm])
        pozm=*it;
        t[*it]=x;
    }
    if(pozm==-1)
    lant[x]=++nrl;
    else
    lant[x]=lant[pozm];
    l[lant[x]].pb(x);
}
inline void construieste(int x,int nod,int li,int ls){
    if(li==ls)
    {
        aint[x][nod]=val[l[x][li-1]];
        return ;
    }
    int mij=(li+ls)>>1;
    construieste(x,nod*2,li,mij);
    construieste(x,nod*2+1,mij+1,ls);
    aint[x][nod]=max(aint[x][nod*2],aint[x][nod*2+1]);
}
inline void dfs2(int x){
    for(vector<int>::iterator it=v[x].begin();it!=v[x].end();++it)
    if(*it!=t[x])
    {
        if(lant[x]!=lant[*it])
        niv[lant[*it]]=niv[lant[x]]+1;
        dfs2(*it);
    }
}
inline void update(int x,int nod,int li,int ls,int poz,int val){
    if(li==ls)
    {
        aint[x][nod]=val;
        return ;
    }
    int mij=(li+ls)>>1;
    if(poz<=mij)
    update(x,nod*2,li,mij,poz,val);
    else
    update(x,nod*2+1,mij+1,ls,poz,val);
    aint[x][nod]=max(aint[x][nod*2],aint[x][nod*2+1]);
}
inline int query(int x,int nod,int li,int ls,int st,int dr){
    if(st<=li&&ls<=dr)
    {
        return aint[x][nod];
    }
    int mij=(li+ls)>>1,xx=0;
    if(st<=mij)
    xx=max(xx,query(x,nod*2,li,mij,st,dr));
    if(mij<dr)
    xx=max(xx,query(x,nod*2+1,mij+1,ls,st,dr));
    return xx;
}
int main()
{
    f>>n>>m;
    for(i=1;i<=n;++i)
    f>>val[i];
    for(i=1;i<n;++i)
    {
        f>>x>>y;
        v[x].pb(y);
        v[y].pb(x);
    }
    dfs(1);
    for(i=1;i<=nrl;++i)
    {
        reverse(l[i].begin(),l[i].end());
        for(j=0;j<l[i].size();++j)
        poz[l[i][j]]=j+1;
        aint[i].resize(4*l[i].size());
        construieste(i,1,1,l[i].size());
    }
    dfs2(1);
    for(i=1;i<=n;++i)
    if(lant[t[i]]!=lant[i])
    tata[lant[i]]=t[i];
    for(i=1;i<=m;++i)
    {
        f>>tip>>x>>y;
        if(tip==0)
        {
            update(lant[x],1,1,l[lant[x]].size(),poz[x],y);
            continue;
        }
        sol=0;
        l1=lant[x];
        l2=lant[y];
        while(l1!=l2)
        {
            if(niv[l1]<niv[l2])
            {
                sol=max(sol,query(l2,1,1,l[l2].size(),1,poz[y]));
                y=tata[l2];
                l2=lant[y];
            }
            else
            {
                sol=max(sol,query(l1,1,1,l[l1].size(),1,poz[x]));
                x=tata[l1];
                l1=lant[x];
            }
        }
        if(poz[x]>poz[y])
        swap(x,y);
        sol=max(sol,query(l1,1,1,l[l1].size(),poz[x],poz[y]));
        g<<sol<<'\n';
    }
    return 0;
}