Cod sursa(job #1805548)

Utilizator ghost24ghost ghost ghost24 Data 13 noiembrie 2016 22:37:44
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.64 kb
#include <iostream>
#include <fstream>
#include <vector>
#define DX 100010
using namespace std;
fstream fin("heavypath.in",ios::in),fout("heavypath.out",ios::out);
int n,m,val[DX],h[DX],t[DX],w[DX],pid[DX],poz[DX];
vector<vector<int>> v,path;
class arb
{
public:
    arb(const vector<int>& vect)
    {
        for(lmax=1;(1<<lmax)<vect.size();lmax++);lmax=(1<<lmax);
        a=vector<int> (2*lmax);
        for(i=0;i<vect.size();i++) a[lmax+i]=val[vect[i]];
        for(i=lmax-1;i>0;i--) a[i]=max(a[i*2],a[i*2+1]);
    }
    void update(int poz,int valoare)
    {
        poz=poz+lmax;
        a[poz]=valoare;
        while(poz)
        {
            poz=poz/2;
            a[poz]=max(a[2*poz],a[2*poz+1]);
        }
    }
    int query(int st,int dr)
    {
        st+=lmax;dr+=lmax;
        int maxim=0;
        while(st<=dr)
        {
            maxim=max(maxim,max(a[st],a[dr]));
            st=(st+1)/2;dr=(dr-1)/2;
        }
        return maxim;
    }
    int lmax,i;
    vector<int> a;
};
vector<arb> varb;

void citire()
{
    int a,b,i;
    fin>>n>>m;
    v=vector<vector<int> > (n+2,vector<int>());
    for(i=1;i<=n;i++) fin>>val[i];
    for(i=1;i<n;i++)
    {
        fin>>a>>b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
}
void df(int nod)
{
    int i,ales=0;
    w[nod]=1;
    for(i=0;i<v[nod].size();i++)
    {
        if(v[nod][i]!=t[nod])
        {
            t[v[nod][i]]=nod;
            h[v[nod][i]]=h[nod]+1;
            df(v[nod][i]);
            w[nod]+=w[v[nod][i]];
            if(ales==0 || w[ales]<w[v[nod][i]]) ales=v[nod][i];
        }
    }
    pid[nod]=pid[ales];
    if(ales==0)   //frunzulita
    {
        pid[nod]=path.size();
        path.push_back(vector<int>());
    }
    poz[nod]=path[pid[nod]].size();
    path[pid[nod]].push_back(nod);

}
void make_arbore()
{
    int i;
    h[1]=1;
    df(1);
    for(i=0;i<path.size();i++) //formez arb-orii
    {
        varb.push_back(arb(path[i]));
    }
}
int Query(int a,int b)
{
    int e1,e2,aux;
    if(pid[a]==pid[b])
    {
        if(poz[a]>poz[b]) swap(a,b);
        return varb[pid[a]].query(poz[a],poz[b]);
    }

    e1=path[pid[a]][path[pid[a]].size()-1]; //elementul din varful lantului in care face parte a-ul
    e2=path[pid[b]][path[pid[b]].size()-1]; //elementul din varful lantului in care face parte b-ul


    if(h[e1]<h[e2])
    {
        swap(e1,e2);
        swap(a,b);
    }

    return max(varb[pid[e1]].query(poz[a],poz[e1]),Query(t[e1],b));

}
int main()
{
    int i,t,a,b;
    citire();
    make_arbore();

    for(i=1;i<=m;i++)
    {
        fin>>t>>a>>b;
        if(t==0)
            varb[pid[a]].update(poz[a],b);
        else
            fout<<Query(a,b)<<"\n";
    }
}