Cod sursa(job #1070372)

Utilizator geniucosOncescu Costin geniucos Data 31 decembrie 2013 19:17:07
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.38 kb
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int po,i,j,x11,y11,Q,p1,p2,sol,X,Y,m,n,tip,nod,val,PP[100009],Path[100009],t[100009],T[100009],niv[100009],Nr[100009],ap[100009],a[100009];
char sir[1100000];
vector < int > muc[100009],V[100009],Aint[100009];
void dfs(int nod)
{
    vector < int > :: iterator it;
    ap[nod]=Nr[nod]=1;
    int pz=-1;
    for(it=muc[nod].begin();it!=muc[nod].end();it++)
        if(ap[*it]==0)
        {
            dfs(*it);
            t[*it]=nod;
            Nr[nod]+=Nr[*it];
            if(pz==-1||Nr[*it]>Nr[pz]) pz=*it;
        }
    if(pz==-1) Path[nod]=++Q;
    else Path[nod]=Path[pz];
    V[Path[nod]].push_back(nod);
}
void dfs2(int nod)
{
    vector < int > :: iterator it;
    for(it=muc[nod].begin();it!=muc[nod].end();it++)
        if(*it!=t[nod])
        {
            if(Path[nod]!=Path[*it]) niv[Path[*it]]=niv[Path[nod]]+1;
            dfs2(*it);
        }
}
void Build(int lv,int nod,int st,int dr)
{
    if(st==dr)
    {
        Aint[lv][nod]=a[V[lv][st-1]];
        return ;
    }
    int mij=(st+dr)>>1;
    Build(lv,nod<<1,st,mij);
    Build(lv,(nod<<1)+1,mij+1,dr);
    Aint[lv][nod]=max(Aint[lv][nod<<1],Aint[lv][(nod<<1)+1]);
}
void Update(int lv,int nod,int st,int dr,int poz,int val)
{
    if(st==dr)
    {
        Aint[lv][nod]=val;
        return ;
    }
    int mij=(st+dr)>>1;
    if(poz<=mij) Update(lv,nod<<1,st,mij,poz,val);
    else Update(lv,(nod<<1)+1,mij+1,dr,poz,val);
    Aint[lv][nod]=max(Aint[lv][nod<<1],Aint[lv][(nod<<1)+1]);
}
int Query(int lv,int nod,int st,int dr,int x,int y)
{
    if(x<=st&&dr<=y) return Aint[lv][nod];
    int mij=(st+dr)>>1,maxi=0;
    if(x<=mij) maxi=Query(lv,nod<<1,st,mij,x,y);
    if(y>mij) maxi=max(maxi,Query(lv,(nod<<1)+1,mij+1,dr,x,y));
    return maxi;
}
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
scanf("%d",&n);
scanf("%d\n",&m);
gets(sir+1);
po=1;
for(i=1;i<=n;i++)
{
    while(sir[po]>='0'&&sir[po]<='9') a[i]=a[i]*10+sir[po++]-48;
    po++;
}
for(i=1;i<n;i++)
{
    scanf("%d",&x11);
    scanf("%d",&y11);
    muc[x11].push_back(y11);
    muc[y11].push_back(x11);
}
dfs(1);
for(i=1;i<=Q;i++)
{
    reverse(V[i].begin(),V[i].end());
    for(j=0;j<V[i].size();j++)
        PP[V[i][j]]=j+1;
    Aint[i].resize(V[i].size()*4);
    Build(i,1,1,V[i].size());
}
dfs2(1);
for(i=2;i<=n;i++)
    if(Path[t[i]]!=Path[i])
        T[Path[i]]=t[i];
while(m)
{
    m--;
    scanf("%d",&tip);
    if(tip==0)
    {
        scanf("%d",&nod);
        scanf("%d",&val);
        Update(Path[nod],1,1,V[Path[nod]].size(),PP[nod],val);
    }
    else
    {
        scanf("%d",&X);
        scanf("%d",&Y);
        sol=0;
        p1=Path[X];
        p2=Path[Y];
        sol=0;
        while(p1!=p2)
        {
            if(niv[p1]<niv[p2])
            {
                sol=max(sol,Query(p2,1,1,V[p2].size(),1,PP[Y]));
                Y=T[p2];
                p2=Path[T[p2]];
            }
            else
            {
                sol=max(sol,Query(p1,1,1,V[p1].size(),1,PP[X]));
                X=T[p1];
                p1=Path[T[p1]];
            }
        }
        if(PP[X]<PP[Y]) sol=max(sol,Query(p1,1,1,V[p1].size(),PP[X],PP[Y]));
        else sol=max(sol,Query(p1,1,1,V[p1].size(),PP[Y],PP[X]));
        printf("%d\n",sol);
    }
}
return 0;
}