Cod sursa(job #809176)

Utilizator PlayLikeNeverB4George Marcus PlayLikeNeverB4 Data 7 noiembrie 2012 23:15:21
Problema Heavy Path Decomposition Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.95 kb
#include <cstdio>
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <ctype.h>
#include <cstring>
#include <ctime>

using namespace std;

#define MAXN 100005
int N, M, t, x, y;
int val[MAXN];
vector<int> A[MAXN];
int T[MAXN];
int lvl[MAXN];
int *Aint[MAXN];
bool viz[MAXN];
vector<int> lant[MAXN];
int nrLant;
int inLant[MAXN];
int pos[MAXN];

int dfs(int node, int prev) {
    viz[node] = true;
    T[node] = prev;
    lvl[node] = lvl[prev] + 1;

    int maxNrFii = 0;
    int pmax = -1;
    int nrFii = 0;
    int crt;
    for(vector<int> :: iterator it = A[node].begin(); it != A[node].end(); it++)
        if(!viz[*it]) {
            crt = dfs(*it, node);
            nrFii += crt;
            if(crt > maxNrFii) {
                maxNrFii = crt;
                pmax = *it;
            }
        }

    if(maxNrFii == 0) {
        inLant[node] = nrLant;
        lant[nrLant].push_back(node);
        nrLant++;
    }
    else {
        int Lmax = inLant[pmax];
        inLant[node] = Lmax;
        lant[Lmax].push_back(node);
    }

    return nrFii;
}

inline int tataLant(int nod) {
    return T[lant[inLant[nod]][0]];
}

void init(int idxLant, int k, int st, int dr) {
    if(st == dr) {
        Aint[idxLant][k] = val[lant[idxLant][st - 1]];
        return;
    }

    int m = (st + dr) / 2;
    init(idxLant, 2 * k, st, m);
    init(idxLant, 2 * k + 1, m + 1, dr);

    Aint[idxLant][k] = max(Aint[idxLant][2 * k], Aint[idxLant][2 * k + 1]);
}

void update(int idxLant, int k, int st, int dr, int qpos) {
    if(st == dr) {
        Aint[idxLant][k] = y;
        return;
    }

    int m = (st + dr) / 2;
    if(qpos <= m)
        update(idxLant, 2 * k, st, m, qpos);
    else
        update(idxLant, 2 * k + 1, m + 1, dr, qpos);

    Aint[idxLant][k] = max(Aint[idxLant][2 * k], Aint[idxLant][2 * k + 1]);
}

int query(int idxLant, int k, int st, int dr, int qst, int qdr) {
    if(qst <= st && dr <= qdr) {
        return Aint[idxLant][k];
    }

    int m = (st + dr) / 2;
    int ret = 0;
    if(qst <= m)
        ret = max(ret, query(idxLant, 2 * k, st, m, qst, qdr));
    if(qdr > m)
        ret = max(ret, query(idxLant, 2 * k + 1, m + 1, dr, qst, qdr));

    return ret;
}

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

    scanf("%d %d", &N, &M);
    for(int i = 1; i <= N; i++)
        scanf("%d", &val[i]);
    for(int i = 0; i < N - 1; i++) {
        scanf("%d %d", &x, &y);
        A[x].push_back(y);
        A[y].push_back(x);
    }

    lvl[0] = 0;
    dfs(1, 0);

    for(int i = 0; i < nrLant; i++) {
        reverse(lant[i].begin(), lant[i].end());
        Aint[i] = new int[4 * (int)lant[i].size()];
        init(i, 1, 1, (int)lant[i].size());
        for(vector<int> :: iterator it = lant[i].begin(); it != lant[i].end(); it++)
            pos[*it] = (it - lant[i].begin()) + 1;
    }

    for(int i = 0; i < M; i++) {
        scanf("%d %d %d", &t, &x, &y);

        if(t == 1) {
            int ans = 0;
            while(true) {
                if(inLant[x] == inLant[y]) {
                    int left = min(pos[x], pos[y]);
                    int right = max(pos[x], pos[y]);
                    ans = max(ans, query(inLant[x], 1, 1, lant[inLant[x]].size(), left, right));
                    break;
                }

                if(lvl[tataLant(x)] < lvl[tataLant(y)])
                    swap(x, y);

                ans = max(ans, query(inLant[x], 1, 1, lant[inLant[x]].size(), 1, pos[x]));
                x = tataLant(x);
            }

            printf("%d\n", ans);
        }
        else {
            int crtL = inLant[x];
            update(crtL, 1, 1, lant[crtL].size(), pos[x]);
        }
    }

	return 0;
}