Cod sursa(job #2120642)

Utilizator tifui.alexandruTifui Ioan Alexandru tifui.alexandru Data 2 februarie 2018 18:49:16
Problema Heavy Path Decomposition Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.31 kb
#include <bits/stdc++.h>
#define Nmax 100001
#define ls ((1<<(nod+1))-1)
#define rs (1<<(nod+1))
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int v[Nmax],nr_chain[Nmax],poz[Nmax],lvl[Nmax],weight[Nmax],t[Nmax];
list <int> arb[Nmax];
vector <int> chain[Nmax];
vector <int> Aint[Nmax];
int N,changed,nr_arb,lsh,rsh;
void DFS(int x)
{
    int nr=0,nod=0;
    for(list <int> :: iterator it=arb[x].begin();it!=arb[x].end();++it)
        if(!lvl[*it])
        {
            nr++;
            t[*it]=x;
            lvl[*it]=lvl[x]+1;
            DFS(*it);
            if(weight[*it]>weight[nod])
                nod=*it;
        }
    weight[x]=nr+1;
    if(nr)
    {
        nr_chain[x]=nr_chain[nod];
        chain[nr_chain[x]].push_back(x);
    }
    else
    {
        nr_chain[x]=++N;
        chain[N].push_back(x);
    }
}
inline bool cmp(const int &x, const int &y)
{
    return lvl[x]<lvl[y];
}
void build(int p, int q, int nod)
{
    if(p==q)
        Aint[nr_arb][nod]=v[chain[nr_arb][p]];
    else
    {
        int m=(p+q)>>1;
        build(p,m,ls);
        build(m+1,q,rs);
        Aint[nr_arb][nod]=max(Aint[nr_arb][ls],Aint[nr_arb][rs]);
    }
}
void update(int p, int q, int nod)
{
    if(p==q) Aint[nr_arb][nod]=v[chain[nr_arb][p]];
    else
    {
        int m=(p+q)>>1;
        if(changed<=m) update(p,m,ls);
        else update(m+1,q,rs);
        Aint[nr_arb][nod]=max(Aint[nr_arb][ls],Aint[nr_arb][rs]);
    }
}
int query(int p, int q, int nod)
{
    if(lsh<=p and q<=rsh) return Aint[nr_arb][nod];
    else
    {
        int m=(p+q)>>1,max1=-INT_MAX,max2=-INT_MAX;
        if(lsh<=m) max1=query(p,m,ls);
        if(m<rsh) max2=query(m+1,q,rs);
        return max(max1,max2);
    }
}
int heavy_path_query(int x, int y)
{
    if(nr_chain[x]==nr_chain[y])
    {
        nr_arb=nr_chain[x];
        lsh=poz[x];
        rsh=poz[y];
        if(lsh>rsh) swap(lsh,rsh);
        return query(0,chain[nr_arb].size()-1,0);
    }
    else
    {
        if(lvl[chain[nr_chain[x]][0]]<lvl[chain[nr_chain[y]][0]]) swap(x,y);
        lsh=0;
        rsh=poz[x];
        nr_arb=nr_chain[x];
        int max1=query(0,chain[nr_arb].size()-1,0);
        int max2=heavy_path_query(t[chain[nr_chain[x]][0]],y);
        return max(max1,max2);
    }
}
int main()
{
    int n,Q,i,j,x,y,op;
    f>>n>>Q;
    for(i=1;i<=n;i++)
        f>>v[i];
    for(i=1;i<n;i++)
    {
        f>>x>>y;
        arb[x].push_back(y);
        arb[y].push_back(x);
    }
    lvl[1]=1;
    DFS(1);
    for(i=1;i<=N;i++)
    {
        sort(chain[i].begin(),chain[i].end(),cmp);
        for(j=0;j<(int)chain[i].size();j++)
            poz[chain[i][j]]=j;
        Aint[i].reserve(20*chain[i].size());
        nr_arb=i;
        build(0,chain[i].size()-1,0);
    }
    while(Q--)
    {
        f>>op>>x>>y;
        switch(op)
        {
            case 0:
                {
                    v[x]=y;
                    nr_arb=nr_chain[x];
                    changed=poz[x];
                    update(0,chain[nr_arb].size()-1,0);

                    break;
                }
            case 1:
                {
                    g<<heavy_path_query(x,y)<<'\n';

                    break;
                }
        }
    }

    return 0;
}