Cod sursa(job #1223862)

Utilizator Luncasu_VictorVictor Luncasu Luncasu_Victor Data 29 august 2014 00:57:16
Problema Heavy Path Decomposition Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.1 kb
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
#define MAX 100010

vector<int> Edge[MAX];
vector<int> Path[MAX];
bool Visited[MAX];
int N, M, Value[MAX], Height[MAX], Degree[MAX], Parent[MAX], pathHead[MAX], whatPath[MAX], posInPath[MAX], nrPaths;

void DFS(int X, int height) {
	int Y = 0;
	Visited[X] = true;
	Height[X] = height;
	for (int i = 0; i < Edge[X].size(); i++) {
		if (!Visited[Edge[X][i]]) {
			DFS(Edge[X][i], height + 1);
			Parent[Edge[X][i]] = X;
			Degree[X] += Degree[Edge[X][i]];
			if (Degree[Edge[X][i]] > Degree[Y]) {
				Y = Edge[X][i];
			}
		}
	}
	if (Degree[X] == 0) {
		nrPaths++;
		Path[nrPaths].push_back(X);	
		whatPath[X] = nrPaths;
	} else {
		whatPath[X] = whatPath[Y];
		Path[whatPath[X]].push_back(X);	
	}
	Degree[X]++;
}

void update(vector<int> &Tree, int Node, int L, int R, int position, int value) {
	if (L == R) {
		Tree[Node] = value;
	} else {
		int M = (L + R) / 2;
		if (position <= M) 
			update(Tree, 2*Node, L, M, position, value);
		else
			update(Tree, 2*Node+1, M+1, R, position, value);
			Tree[Node] = max(Tree[2*Node], Tree[2*Node+1]);
	}
}

int query(vector<int> &Tree, int Node, int L, int R, int Lo, int Hi) {
	if (Lo <= L && R <= Hi) {
		return Tree[Node];
	} else {
		int Q, M = (L + R) / 2;
		if (Lo <= M) 
			Q = query(Tree, 2*Node, L, M, Lo, Hi);
		if (Hi > M) 
			Q = max(Q, query(Tree, 2*Node+1, M+1, R, Lo, Hi));
		return Q;
	}
}

int main() {
	int X, O, Y;

	freopen("heavypath.in","r",stdin);
	freopen("heavypath.out","w",stdout);
	
	scanf("%d %d", &N, &M);
	for (int i = 1; i <= N; i++) {
		scanf("%d", &Value[i]);
	}
	for (int i = 1; i < N; i++){
		scanf("%d %d", &X, &Y);
		Edge[X].push_back(Y);
		Edge[Y].push_back(X);
	}
	
	DFS(1, 1);
	
	for (int i = 1; i <= nrPaths; i++) {
		X = Path[i].size();
		reverse(Path[i].begin(), Path[i].end());
		Path[i].resize(3 * X);
		for (int j = X; j > 0; j--) {
			Path[i][j] = Path[i][j-1];
			posInPath[Path[i][j]] = j;
			Parent[Path[i][j]] = Parent[Path[i][1]];
			pathHead[Path[i][j]] = Path[i][1];
		}
		Path[i][0] = X;
	}
	
	for (int i = 1; i <= N; i++) {
		update(Path[whatPath[i]], 1, 1, Path[whatPath[i]][0], posInPath[i], Value[i]);
	}
	
	while (M--) {
		scanf("%d %d %d", &O, &X, &Y);
		if (O == 0) {
			update(Path[whatPath[X]], 1, 1, Path[whatPath[X]][0], posInPath[X], Y);
		} else {
			int Answer = 0;
			while (whatPath[X] != whatPath[Y]) {
				if (Height[pathHead[X]] > Height[pathHead[Y]]) {
					Answer = max(Answer, query(Path[whatPath[X]], 1, 1, Path[whatPath[X]][0], 1, posInPath[X]));
					X = Parent[pathHead[X]];
				} else {
					Answer = max(Answer, query(Path[whatPath[Y]], 1, 1, Path[whatPath[Y]][0], 1, posInPath[Y]));
					Y = Parent[pathHead[Y]];
				}
			}
			if (posInPath[X] > posInPath[Y]) swap(X, Y);
			Answer = max(Answer, query(Path[whatPath[X]], 1, 1, Path[whatPath[X]][0], posInPath[X], posInPath[Y]));
			printf("%d\n", Answer);
		}
	}
		
	return 0;
}