Cod sursa(job #718479)

Utilizator andunhillMacarescu Sebastian andunhill Data 20 martie 2012 20:32:22
Problema Heavy Path Decomposition Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 3.15 kb
#include<fstream>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

ifstream f("heavypath.in");
ofstream g("heavypath.out");

class arbint
{	 int *A;
	
public:
	int dim;
	int x, y, pos, val, ans;
	
	void init(int d)
	{	dim = d;
		A = new int[4 * d];
	}
	
	void update(int node, int left, int right)
	{	if(left == right)
		{	A[node] = val;
			return;
		}
		
		int mid = (left + right) / 2;
		if(pos <= mid) update(2 * node, left, mid);
		else update(2 * node + 1, mid + 1, right);
		
		A[node] = max(A[2 * node], A[2 * node + 1]);
	}
	
	void query(int node, int left, int right)
	{	if(x <= left && right <= y)
		{	ans = max(ans, A[node]);
			return;
		}
		
		int mid = (left + right) / 2;
		
		if(x <= mid) query(2 * node, left, mid);
		if(mid < y) query(2 * node + 1, mid + 1, right);
	}
};







int N, M;
int nr_ch;				//nr of chains

int v[100001];
int dad[100001];
int ch[100001];			//ch[i] = the chain that i belongs to
int lvl[100001];		//lvl[i] = level of node i
int pos_in[100001];		//position of node i in it's list

vector<int>graph[100001];
vector<int>chains[100001];

arbint arb[100001];

typedef vector<int>::iterator it;

bool cmp(int a, int b)
{	return lvl[a] < lvl[b];
}


void DFS(int node)
{	int son, mv;
	
	lvl[node] = lvl[dad[node]] + 1;
	
	son = 0;
	mv = 0;
	for(it i = graph[node].begin(); i != graph[node].end(); i++)
	{	if(*i == dad[node]) continue;
		
		dad[*i] = node;
		DFS(*i);
		
		if(mv < chains[ch[*i]].size())
			mv = chains[ch[*i]].size(), son = *i;
	}
	
	if(mv == 0)
	{	chains[++nr_ch].push_back(node);
		ch[node] = nr_ch;
	}
	else 
	{	chains[ch[son]].push_back(node);
		ch[node] = ch[son];
	}
}

int get_max(int x, int y)
{	if(ch[x] == ch[y])
	{	arb[ch[x]].ans = -1;
		arb[ch[x]].x = min(pos_in[x], pos_in[y]);
		arb[ch[x]].y = max(pos_in[x], pos_in[y]);
		
		arb[ch[x]].query(1, 0, arb[ch[x]].dim - 1);
		return arb[ch[x]].ans;
	}
	
	if(lvl[dad[*chains[ch[x]].begin()]] < lvl[dad[*chains[ch[y]].begin()]])
		swap(x, y);
	
	arb[ch[x]].ans = -1;
	arb[ch[x]].x = 0;
	arb[ch[x]].y = pos_in[x];
	arb[ch[x]].query(1, 0, arb[ch[x]].dim - 1);
	
	int ans = arb[ch[x]].ans;
	
	x = dad[*chains[ch[x]].begin()];
	int ret = get_max(x, y);
	
	return max(ret, ans);
}

int main()
{	int i, j, x, y;
	
	f>>N>>M;
	for(i = 1; i <= N; i++)
		f>>v[i];
	for(i = 1; i < N; i++)
	{	f>>x>>y;
		graph[x].push_back(y);
		graph[y].push_back(x);
	}
	
	DFS(1);
	
	for(i = 1; i <= nr_ch; i++)
	{	sort(chains[i].begin(), chains[i].end(), cmp);
		arb[i].init(chains[i].size());
		for(j = 0; j < chains[i].size(); j++)
		{	arb[i].pos = j;
			arb[i].val = v[chains[i][j]];
			arb[i].update(1, 0, arb[i].dim - 1);
			
			pos_in[chains[i][j]] = j;
		}
	}
	
	for(i = 1; i <= M; i++)
	{	f>>j>>x>>y;
		
		if(j == 0)
		{	arb[ch[x]].pos = pos_in[x];
			arb[ch[x]].val = y;
			arb[ch[x]].update(1, 0 , arb[ch[x]].dim - 1);
		}
		else
			g<<get_max(x, y)<<'\n';
	}
	
	/*for(i = 1; i <= nr_ch; i++)
	{	for(it k = chains[i].begin(); k != chains[i].end(); k++)
			cout<<*k<<" ";
		cout<<'\n';
	}*/
	
	f.close();
	g.close();
	return 0;
}