Cod sursa(job #1768355)

Utilizator Alexa2001Alexa Tudose Alexa2001 Data 30 septembrie 2016 19:32:04
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.86 kb
#include <bits/stdc++.h>
#define mid ((st+dr)>>1)
#define left_son (node<<1)
#define right_son ((node<<1)+1)

using namespace std;

const int Nmax = 1e5+5;

int *aint[Nmax];

int q, x, y, n, i, nr, qq;
int dad[Nmax], l[Nmax], w[Nmax], level[Nmax], to[Nmax], pos[Nmax], val[Nmax];

vector<int> edge[Nmax], sons[Nmax], chain[Nmax];

void dfs(int node)
{
    w[node] = 1;

    for(auto it : edge[node])
    if(!level[it])
    {
        sons[node].push_back(it);
        dad[it] = node;
        level[it] = level[node]+1;
        dfs(it);
        w[node] += w[it];
    }
}

void chains(int node)
{
    to[node] = nr;
    chain[nr].push_back(node);
    pos[node] = chain[nr].size();

    int Max=0, xson=0;

    for(auto it : sons[node])
        if(Max < w[it]) Max = w[it], xson=it;

    if(xson) chains(xson);

    for(auto it : sons[node])
        if(it!=xson)
        {
            ++nr;
            chains(it);
        }
}

void build(int ind, int node, int st, int dr)
{
    if(st==dr)
    {
        aint[ind][node] = val[chain[ind][st-1]];
        return;
    }

    build(ind, left_son, st, mid);
    build(ind, right_son, mid+1, dr);

    aint[ind][node] = max(aint[ind][left_son], aint[ind][right_son]);
}

void update(int ind, int node, int st, int dr, int target, int val)
{
    if(st==dr)
    {
        aint[ind][node] = val;
        return;
    }

    if(target<=mid) update(ind, left_son, st, mid, target, val);
    else update(ind, right_son, mid+1, dr, target, val);

    aint[ind][node] = max(aint[ind][left_son], aint[ind][right_son]);
}

int query(int ind, int node, int st, int dr, int Left, int Right)
{
    if(Left<=st && dr<=Right)
        return aint[ind][node];

    int ans = 0;
    if(Left<=mid) ans = max(ans, query(ind, left_son, st, mid, Left, Right));
    if(mid<Right) ans = max(ans, query(ind, right_son, mid+1, dr, Left, Right));

    return ans;
}

int go(int x, int y)
{
    if(to[x]==to[y])
    {
        if(pos[x]>pos[y]) swap(x,y);
        return query(to[x], 1, 1, l[to[x]], pos[x], pos[y]);
    }

    int dadx = chain[to[x]][0], dady = chain[to[y]][0];

    if(level[dadx]<level[dady])
    {
        swap(x,y);
        swap(dadx, dady);
    }

    return max( query(to[x], 1, 1, l[to[x]], 1, pos[x]), go(dad[dadx], y) );
}

int main()
{
    freopen("heavypath.in", "r", stdin);
    freopen("heavypath.out", "w", stdout);

    scanf("%d%d", &n, &q);

    for(i=1; i<=n; ++i) scanf("%d", &val[i]);

    for(i=1; i<n; ++i)
    {
        scanf("%d%d", &x, &y);
        edge[x].push_back(y);
        edge[y].push_back(x);
    }

    level[1] = nr = 1;
    dfs(1);
    chains(1);

    for(i=1; i<=nr; ++i)
    {
        l[i] = chain[i].size();
        aint[i] = new int [l[i]<<2];
        build(i, 1, 1, l[i]);
    }

    while(q--)
    {
        scanf("%d%d%d", &qq, &x, &y);

        if(qq==0) update(to[x], 1, 1, l[to[x]], pos[x], y);
        else printf("%d\n", go(x,y));
    }

    return 0;
}