Cod sursa(job #2196239)

Utilizator Vlad_lsc2008Lungu Vlad Vlad_lsc2008 Data 18 aprilie 2018 21:30:24
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.27 kb
#include<fstream>
#include<iostream>
#include<vector>
#include<bitset>
#define nmax 100005
using namespace std;

int n,m1;
int nrlanturi;
int poz[nmax];
int lant[nmax];
int nivel[nmax];
int val[nmax];
int tata[nmax];
vector<int> m[nmax];
vector< vector<int> > lanturi;
vector< vector<int> > arbint;
vector<int> parinte;
bitset<nmax> viz;

int dfs(int nod,int niv)
{
    int subarbmax=-1,subarb,df,nrfii=0,ok;
    viz[nod]=1;
    nivel[nod]=niv;
    ok=1;
    for(vector<int>::iterator it=m[nod].begin();it!=m[nod].end();it++)
        if(!viz[*it])
        {
            tata[*it]=nod;
            ok=0;
            df=dfs(*it,niv+1);
            if(subarbmax<df)
            {
                subarbmax=df;
                subarb=lant[*it];
            }
            nrfii+=df;
        }
    if(ok)
    {
        vector<int> aux;
        aux.push_back(nod);
        poz[nod]=0;
        lant[nod]=nrlanturi;
        lanturi.push_back(aux);
        parinte.push_back(tata[nod]);
        nrlanturi++;
        return 1;
    }
    poz[nod]=lanturi[ subarb ].size();
    lant[nod]=subarb;
    lanturi[subarb].push_back(nod);
    parinte[ subarb ] = tata[nod];
    return nrfii+1;
}

void update(int pozvecarb, int st,int dr,int p,int val,int poz)
{
    if(st==dr)
    {
        arbint[pozvecarb][p]=val;
        return;
    }
    int mij= st + (dr-st)/2;
    if( mij< poz) update(pozvecarb,mij+1,dr,2*p+1,val,poz);
    else update(pozvecarb,st,mij,2*p,val,poz);
    arbint[pozvecarb][p]=max( arbint[pozvecarb][2*p], arbint[ pozvecarb][2*p+1] );
}

int querry(int pozvecarb,int st,int dr,int p,int a,int b)
{
    if( st>=a && dr<=b ) return arbint[pozvecarb][p];
    int maxi=-5,mij = st + (dr-st)/2;
    if( mij < b ) maxi=max(maxi,querry(pozvecarb,mij+1,dr,2*p+1,a,b));
    if( mij >= a) maxi=max(maxi,querry(pozvecarb,st,mij,2*p,a,b));
    return maxi;
}

int main()
{
    int i,j;
    ifstream t1("heavypath.in");
    ofstream t2("heavypath.out");
    t1>>n>>m1;
    for(i=1;i<=n;i++)
    {
        t1>>val[i];
    }
    int a,b;
    for(i=1;i<n;i++)
    {
        t1>>a>>b;
        m[a].push_back(b);
        m[b].push_back(a);
    }

    nivel[0]=-1;
    dfs(1,0); //constructie lanturi
    /*for(i=0;i<nrlanturi;i++)
        cout<<parinte[i]<<' '; cout<<'\n';
    for(i=1;i<=n;i++)
        cout<<lant[i]<<' '; cout<<'\n';
    for(i=1;i<=n;i++)
        cout<<poz[i]<<' '; cout<<'\n';
    for(i=1;i<=n;i++)
        cout<<nivel[i]<<' '; cout<<'\n';
    for(i=0;i<lanturi.size();i++)
    {
        for(j=0;j<lanturi[i].size();j++)
            cout<<lanturi[i][j]<<' '<<val[lanturi[i][j]]<<"    "; cout<<'\n';
    }*/

    for(i=0;i<nrlanturi;i++) //fac arborii de intervale
    {
        vector<int> aux;
        arbint.push_back(aux);
        arbint[i].resize(4*lanturi[i].size());
        for(j=0;j<lanturi[i].size();j++)
            update(i,1,lanturi[i].size(),1,val[lanturi[i][j]],j+1);
    }
    /*for(i=0;i<nrlanturi;i++)
    {
        for(j=1;j<arbint[i].size();j++) cout<<arbint[i][j]<<' '; cout<<'\n';
    }*/
    int c,sol;
    int nr=0;
    for(;m1;m1--)
    {
        t1>>a>>b>>c;
        if(a==0)
        {
            update(lant[b],1,lanturi[ lant[b] ].size(),1,c,poz[b]+1);
        }
        else
        {
            sol=0;
            while( lant[b]!=lant[c] )
            {
               // cout<<b<<' '<<c<<' '<<parinte[lant[b]]<<' '<<parinte[lant[c]]<<' '<<nivel[parinte[lant[b]]]<<' '<<nivel[parinte[lant[c]]]<<'\n';
                //if(nr==15) break;
                //nr++;
                if( nivel[ parinte[lant[b] ]] > nivel[ parinte [ lant[c] ] ] )
                {
                    sol=max(sol, querry(lant[b],1,lanturi[ lant[b]].size(),1, poz[b]+1, lanturi[ lant[b]].size() ) );
                    b=parinte[ lant[b]];
                }
                else
                {
                    sol=max(sol, querry(lant[c],1,lanturi[ lant[c]].size(),1, poz[c]+1, lanturi[ lant[c]].size() ) );
                    c=parinte[lant[c]];
                }
            }
            sol=max(sol,querry(lant[c],1,lanturi[ lant[c]].size(),1, min( poz[c]+1,poz[b]+1) , max(poz[c]+1,poz[b]+1) ) );
            t2<<sol<<'\n';
        }
    }
    t1.close();
    t2.close();
    return 0;
}