Cod sursa(job #1266897)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 19 noiembrie 2014 11:34:11
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.29 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int N,M;
vector <int> G[100005];
vector <int> P[100005];
int Value[100005];
int Arb[4*100005];
int Poz[100005];
int Heavy[100005],L[100005],nbL,Father[100005],LNiv[100005],Level[100005];
void Read()
{
    int i;
    f>>N>>M;
    for(int i=1;i<=N;i++)
        f>>Value[i];
    for(i=1;i<=M;i++)
    {
        int x,y;
        f>>x>>y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
}

void DFS(int node,int father)
{
    bool leaf=1;
    Heavy[node]=1;
    int poz=-1;
    for(int i=0;i<G[node].size();i++)
    {
        int neighb=G[node][i];
        if(neighb==father)
            continue;
      Level[neighb]=Level[node]+1;
        leaf=0;
        DFS(neighb,node);
        Heavy[node]+=Heavy[neighb];
        if(poz==-1)
            poz=neighb;
        else
            if(Heavy[poz]<Heavy[neighb])
                poz=neighb;
    }
    if(leaf==1)
    {
        L[node]=++nbL;
        P[nbL].push_back(node);
        return;
    }
    L[node]=L[poz];
    P[L[poz]].push_back(node);
    for(int i=0;i<G[node].size();i++)
    {
        int neighb=G[node][i];
        if(neighb==father || neighb==poz)
            continue;
        Father[L[neighb]]=node;
        LNiv[L[neighb]]=Level[node];
    }
}
void Build(int K,int A,int B,int dec,int chain)
{
    if(A>B)
        return;
    if(A==B)
    {
        Arb[K+dec]=Value[P[chain][A-1]];
        return;
    }
    Build(2*K,A,(A+B)/2,dec,chain);
    Build(2*K+1,(A+B)/2+1,B,dec,chain);
    Arb[K+dec]=max(Arb[2*K+dec],Arb[2*K+1+dec]);
}
void Update(int K,int A,int B,int dec,int poz,int val)
{
    if(A>B || A>poz || B<poz)
        return;
    if(A==B)
    {
        Arb[K+dec]=val;
        return;
    }
    Update(2*K,A,(A+B)/2,dec,poz,val);
    Update(2*K+1,(A+B)/2+1,B,dec,poz,val);
    Arb[K+dec]=max(Arb[2*K+dec],Arb[2*K+1+dec]);
}

int Query(int K,int A,int B,int dec,int poz,int poz2)
{
    if(A>B || A>poz2 || B<poz)
        return 0;
    if(poz<=A && B<=poz2)
    {
        return Arb[K+dec];
    }
    return (max(Query(2*K,A,(A+B)/2,dec,poz,poz2),Query(2*K+1,(A+B)/2+1,B,dec,poz,poz2)));
}

void Browse()
{
    int i;
    for(i=1;i<=M;i++)
    {
        int type,x,y;
        f>>type>>x>>y;
        if(type==0)
            Update(1,1,P[L[x]].size(),Poz[L[x]],Level[x]-LNiv[L[x]],y);
        else
        {
            int Max=0;
            if(L[x]==L[y])
            {
                if(Level[x]>Level[y])
                    swap(x,y);
                g<<max(Max,Query(1,1,P[L[x]].size(),Poz[L[x]],Level[x]-LNiv[L[x]],Level[y]-LNiv[L[x]]))<<"\n";
            }
            else
            {
                if(LNiv[x]>LNiv[y])
                    swap(x,y);
                Max=max(Max,Query(1,1,P[L[x]].size(),1,Poz[L[x]],Level[x]-LNiv[x]));
                x=Father[L[x]];
            }
        }
    }
}
void Path()
{
    Level[1]=1;
    DFS(1,0);
    for(int i=1;i<=nbL;i++)
    {
        reverse(P[i].begin(),P[i].end());
        if(i>1)
            Poz[i]=Poz[i-1]+4*P[i].size();
        Build(1,1,P[i].size(),Poz[i],i);
    }
}
int main()
{
    Read();
    Path();
    Browse();
    return 0;
}