Cod sursa(job #2206500)

Utilizator Laura_CorneiLaura Maria Cornei Laura_Cornei Data 22 mai 2018 19:32:35
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.32 kb
#include <fstream>
#include <vector>
#define nmax 100005
using namespace std;
fstream f1("heavypath.in", ios::in);
fstream f2("heavypath.out", ios::out);
int n, m, val[nmax], t[nmax], siz[nmax], niv[nmax], urm[nmax], th[nmax], viz[nmax], nrl, sizlant[nmax], indl[nmax], poz[nmax];
vector<int> lant[nmax], v[nmax], aint[nmax];
void citire()
{
    int i, x, y;
    f1>>n>>m;
    for(i=1; i<=n; i++)
        f1>>val[i];
    for(i=1; i<n; i++)
    {
        f1>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
}
void dfs(int nod)
{
    viz[nod]=1;
    siz[nod]=1;
    for(auto it=v[nod].begin(); it!=v[nod].end(); ++it)
        if(!viz[*it])
    {
        niv[*it]=niv[nod]+1;
        dfs(*it);
        siz[nod]+=siz[*it];
        t[*it]=nod;
    }
}
void dfs2(int nod)
{
    if(siz[nod]==1)
    {
        nrl++;
        lant[nrl].push_back(nod);
        sizlant[nrl]=1;
        indl[nod]=nrl;
        poz[nod]=1;
    }
    else
    {
        int maxi=0, vec;
        for(auto it=v[nod].begin(); it!=v[nod].end(); ++it)
            if((*it!= t[nod])&&(maxi< siz[*it])) {maxi=siz[*it]; vec=*it;}
        th[vec]=th[nod];
        urm[nod]=vec;
        dfs2(vec);
        for(auto it=v[nod].begin(); it!=v[nod].end(); ++it)
            if((*it!=t[nod])&&(*it!=vec))
              {
                   th[*it]=*it;
                   dfs2(*it);
              }
        lant[indl[vec]].push_back(nod);
        sizlant[indl[vec]]++;
        indl[nod]=indl[vec];
        poz[nod]=lant[indl[vec]].size();
    }
}
///indl[nod]= indice lantului din care face parte nodul;
///poz[nod]=pozitie nod in lant
void update(int ind, int in, int st, int dr, int val, int poz)
{
    if(st==dr) aint[ind][in]=val; //in=poz
    else
    {
        int mijl=(st+dr)/2;
        if(poz<=mijl) update(ind, in*2, st, mijl, val, poz);
        else update(ind, in*2+1, mijl+1, dr, val, poz);
        aint[ind][in]=max(aint[ind][in*2], aint[ind][in*2+1]);
    }
}
void creeaza(int ind, int dim, vector<int> a)
{
    int poz=1;
    for(auto it=a.begin(); it!=a.end(); ++it, poz++)
        update(ind, 1, 1, dim, val[*it], poz);
}
void drumuri()
{
    for(int i=1; i<=nrl; i++)
        {
            aint[i].resize(4*sizlant[i]+5);
            creeaza(i, sizlant[i], lant[i]);
        }
}
int query(int ind, int in, int st, int dr, int l, int r)
{
    if((l<=st)&&(dr<=r)) return aint[ind][in];
    else
    {
        int mijl=(st+dr)/2, max1=0, max2=0;
        if(l<=mijl) max1=query(ind, in*2, st, mijl, l, r);
        if(mijl+1<=r) max2=query(ind, in*2+1, mijl+1, dr, l, r);
        return max(max1, max2);
    }
}
int query_heavy(int x, int y)
{
    if(indl[x]==indl[y]) return query(indl[x], 1, 1, sizlant[indl[x]], min(poz[x], poz[y]), max(poz[x], poz[y]));
    if(niv[th[x]]< niv[th[y]]) swap(x, y);
    ///urc x
    int rez=query(indl[x], 1, 1, sizlant[indl[x]], min(poz[x], poz[th[x]]), max(poz[x], poz[th[x]]));
    return max(rez,query_heavy(t[th[x]],y));
}
void queryuri()
{
    int i, tip, x, y;
    for(i=1; i<=m; i++)
    {
        f1>>tip>>x>>y;
        if(tip==0) update(indl[x], 1, 1, sizlant[indl[x]], y, poz[x]);
        else f2<<query_heavy(x, y)<<"\n";
    }
}
int main()
{
    citire();
    dfs(1); th[1]=1;
    dfs2(1);
    drumuri();
    queryuri();
    return 0;
}