Cod sursa(job #1969264)

Utilizator tudi98Cozma Tudor tudi98 Data 18 aprilie 2017 13:00:43
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.83 kb
#include <bits/stdc++.h>
using namespace std;

#define REP(i,a) for (int i = 0; i < a; i++)
#define FOR(i,a,b) for (int i = a; i <= b; i++)
#define ROF(i,a,b) for (int i = a; i >= b; i--)
#define FOREACH(it,x) for (auto it: (x))
#define pb push_back
#define SZ(x) ((int)(x).size())

const int Nmax = 100000;

int n,m;
int weight[Nmax+1];
int data[Nmax*4+5];
int val[Nmax+1];
vector<int> G[Nmax+1];
vector< vector<int> > chain;
int what_chain[Nmax+1];
int pos_in_chain[Nmax+1];
int pos_in_aint[Nmax+1];
int T[Nmax+1];
int lvl[Nmax+1];

void dfs(int node,int parent)
{
    weight[node] = 1;
    int best = -1;
    FOREACH(it,G[node]) if (it != parent) {
        lvl[it] = lvl[node] + 1; T[it] = node;  dfs(it,node);
        weight[node] += weight[it];
        if (best == -1 || weight[best] < weight[it]) best = it;
    }
    if (best == -1) {
        chain.pb(vector<int>());
        chain.back().pb(node);
        what_chain[node] = SZ(chain) - 1;
        pos_in_chain[node] = 0;
    }
    else {
        chain[what_chain[best]].pb(node);
        what_chain[node] = what_chain[best];
        pos_in_chain[node] = SZ(chain[what_chain[best]]) - 1;
    }
}

void update(int node,int l,int r,int pos,int value)
{
    if (l == r) {
        data[node] = value;
        return;
    }
    int mid = (l + r) >> 1;
    if (pos <= mid) update(node<<1,l,mid,pos,value);
    else update(node<<1|1,mid+1,r,pos,value);
    data[node] = max(data[node<<1],data[node<<1|1]);
}

int query(int node,int l,int r,int a,int b)
{
    if (l > b || r < a) return -1;
    if (l >= a && r <= b) return data[node];
    int mid = (l + r) >> 1;
    return max(query(node<<1,l,mid,a,b),query(node<<1|1,mid+1,r,a,b));
}

void buildHPD()
{
    lvl[1] = 0;
    dfs(1,-1);
    int cpos = 0;
    REP(i,SZ(chain)) {
        REP(j,SZ(chain[i])) {
            ++cpos;
            pos_in_aint[chain[i][j]] = cpos;
            update(1,1,n,cpos,val[chain[i][j]]);
        }
    }
}

int QueryHPD(int x,int y)
{
    int ret = 0;
    while (what_chain[x] != what_chain[y]) {
        if (lvl[chain[what_chain[x]].back()] < lvl[chain[what_chain[y]].back()]) swap(x,y);
        ret = max(ret,query(1,1,n,pos_in_aint[x],pos_in_aint[chain[what_chain[x]].back()]));
        x = T[chain[what_chain[x]].back()];
    }
    if (pos_in_aint[x] > pos_in_aint[y]) swap(x,y);
    return max(ret,query(1,1,n,pos_in_aint[x],pos_in_aint[y]));
}

int main()
{
    ifstream fin("heavypath.in");
    ofstream fout("heavypath.out");

    fin >> n >> m;
    FOR(i,1,n) fin >> val[i];
    FOR(i,1,n-1) {
        int x,y;
        fin >> x >> y;
        G[x].pb(y),G[y].pb(x);
    }
    buildHPD();
    FOR(i,1,m) {
        int t,x,y; fin >> t >> x >> y;
        if (t == 0) update(1,1,n,pos_in_aint[x],y);
        else fout << QueryHPD(x,y) << "\n";
    }
}