Cod sursa(job #2206461)

Utilizator sebi110Ciobanu Sebastian sebi110 Data 22 mai 2018 18:49:38
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.86 kb
#include <fstream>
#include <vector>
#include <string.h>
#define nmax 100000
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
vector<int> arb[nmax+5];
vector<int> v[nmax+5];
vector<int> lanturi[nmax+5];
int val,pos,lef,righ;
int a[nmax+5],lvl[nmax+5],siz[nmax+5],nextintree[nmax+5];
int tatah[nmax+5],lant[nmax+5],nrlant,pozinlant[nmax+5],tata[nmax+5];
bool viz[nmax+5];
void update(int ind,int nod,int st,int dr)
{
    if(st==dr)
    {
        arb[ind][nod]=val;
        return ;
    }
    int mij=(st+dr)/2;
    if(pos<=mij)
    {
        update(ind,nod*2,st,mij);
    }
    else
    {
        update(ind,nod*2+1,mij+1,dr);
    }
    arb[ind][nod]=max(arb[ind][nod*2],arb[ind][nod*2+1]);
}
int querry(int ind,int nod, int st,int dr)
{
    if(lef<=st && dr<=righ)
    {
        return arb[ind][nod];
    }
    int mij=(st+dr)/2,ar=-1,al=-1;
    if(lef<=mij)
    {
        al=querry(ind,nod*2,st,mij);
    }
    if(mij<righ)
    {
        ar=querry(ind,nod*2+1,mij+1,dr);
    }
    return max(ar,al);
}
int solve(int x,int y)
{
    if(lant[x]==lant[y])
    {
        lef=pozinlant[x];
        righ=pozinlant[y];
        if(righ<lef)
            swap(righ,lef);
        return querry(lant[x],1,0,lanturi[lant[x]].size());
    }
    if(lvl[tatah[x]]<lvl[tatah[y]])
        swap(x,y);
    lef=0;
    righ=pozinlant[x];
    int ans=querry(lant[x],1,0,lanturi[lant[x]].size());
    return max(ans,solve(tata[tatah[x]],y));
}
void constr(vector <int> v,int ind)
{
    int i;
    for(i=0;i<4*v.size()+5;i++)
        arb[ind].push_back(0);
    for(i=0;i<v.size();i++)
    {
        val=a[v[i]];
        pos=i;
        update(ind,1,0,v.size());
    }
}
void calcsiz(int nod)//cal csiz[nod]+lvl[nod]+tata[vec]
{
    int i,vec;
    for(i=0;i<v[nod].size();i++)
    {
        vec=v[nod][i];
        if(viz[vec]==0)
        {
            viz[vec]=1;
            lvl[vec]=lvl[nod]+1;
            tata[vec]=nod;
            calcsiz(vec);
            siz[nod]+=siz[vec];
        }
    }
    siz[nod]++;
}
void DFS(int nod)
{
    // tataH + next_in_tree+lant+pozinlant
    int maxsiz=0,heavy=0,i,vec;
    for(i=0;i<v[nod].size();i++)
    {
        vec=v[nod][i];
        if(viz[vec]==0)
        {
            if(siz[vec]>maxsiz)
            {
                maxsiz=siz[vec];
                heavy=vec;
            }
        }
    }
    nextintree[nod]=heavy;
    for(i=0;i<v[nod].size();i++)
    {
        vec=v[nod][i];
        if(viz[vec]==0)
        {
            if(vec==heavy)
            {
                tatah[vec]=tatah[nod];
                lant[vec]=lant[nod];
            }
            else
            {
                tatah[vec]=vec;
                nrlant++;
                lant[vec]=nrlant;
            }
            pozinlant[vec]=lanturi[lant[vec]].size();
            lanturi[lant[vec]].push_back(vec);
            viz[vec]=1;
            DFS(vec);
        }
    }
    //????
}
int main()
{
    int x,y,t,ind,n,m,i;
    f>>n>>m;
    for(i=1;i<=n;i++)
        f>>a[i];
    for(i=1;i<n;i++)
    {
        f>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    viz[1]=1;
    calcsiz(1);
    memset(viz,0,sizeof(viz));
    //pentru 1
    tatah[1]=1;
    lant[1]=1;
    pozinlant[1]=0;
    lanturi[1].push_back(1);
    nrlant=1;
    viz[1]=1;
    DFS(1);
    //contstruiesc arbori pentru fiecare drum
    for(i=1;i<=nrlant;i++)
    {
        constr(lanturi[i],i);
    }
    for(i=1;i<=m;i++)
    {
        f>>t>>x>>y;
        if(t==0)
        {
            //update=> a[x]=y;
            ind=lant[x];
            val=y;
            pos=pozinlant[x];
            update(ind,1,0,lanturi[ind].size());
        }
        else
        {
            //querry()
            g<<solve(x,y)<<'\n';
        }
    }
    return 0;
}