Cod sursa(job #2227083)

Utilizator TheNextGenerationAyy LMAO TheNextGeneration Data 31 iulie 2018 11:11:55
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.14 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
const int NMAX = 1e5+5;
int nrpaths,n;
int v[NMAX],lvl[NMAX],size[NMAX],b4Path[NMAX],ind[NMAX],pos[NMAX],tree[2*NMAX];
vector<int> G[NMAX],path[NMAX];
void dfs(int x, int p)
{
    lvl[x] = lvl[p]+1;
    size[x] = 1;
    int best = 0;
    for (auto it: G[x])
        if (it!=p)
        {
            dfs(it,x);
            size[x]+=size[it];
            if (size[best]<size[it])
                best = it;
        }
    for (auto it: G[x])
        if (it!=p && it!=best)
            b4Path[ind[it]] = x;
    if (!best)
        ind[x] = ++nrpaths;
    else
        ind[x] = ind[best];
    path[ind[x]].push_back(x);
}
void update(int k, int val)
{
    k+=n;
    tree[k] = val;
    for (; k>1; k>>=1)
        tree[k>>1] = max(tree[k],tree[k^1]);
}
int query(int x, int y)
{
    int ans = 0;
    x+=n;
    y+=n;
    for (; x<y; x>>=1, y>>=1)
    {
        if (x&1)
            ans = max(ans,tree[x++]);
        if (y&1)
            ans = max(ans,tree[--y]);
    }
    return ans;
}
int hpd(int x, int y)
{
    int ans = 0;
    while (ind[x]!=ind[y])
    {
        if (lvl[b4Path[ind[x]]]<lvl[b4Path[ind[y]]])
            swap(x,y);
        ans = max(ans,query(pos[x],pos[path[ind[x]].back()]+1));
        x = b4Path[ind[x]];
    }
    if(pos[x]>pos[y])
        swap(x,y);
    return max(ans,query(pos[x],pos[y]+1));
}

int main()
{
    int m;
    in >> n >> m;
    for (int i = 1; i<=n; i++)
        in >> v[i];
    for (int i = 1; i<n; i++)
    {
        int x,y;
        in >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs(1,0);
    int nr = 0;
    for (int i = 1; i<=nrpaths; i++)
        for (auto it: path[i])
        {
            pos[it] = ++nr;
            tree[nr+n] = v[it];
        }
    for (int i = n; i>0; i--)
        tree[i] = max(tree[i<<1],tree[i<<1|1]);
    for (int i = 1; i<=m; i++)
    {
        int t,x,y;
        in >> t >> x >> y;
        if (!t)
            update(pos[x],y);
        else
            out << hpd(x,y) << "\n";
    }
}