Cod sursa(job #1454260)

Utilizator mikeshadowIon Complot mikeshadow Data 25 iunie 2015 22:00:57
Problema Heavy Path Decomposition Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.63 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

#define MAXN 100000

typedef vector<int> vi;

int n;
int initial[MAXN];

vi e[MAXN];


int lv[MAXN];
int sz[MAXN];

int numpaths=1;
int path[MAXN];
int pp[MAXN];
int parent[MAXN+5];
int lenpath[MAXN+5];
int lvpath[MAXN+5];

struct node
{
	node *l, *r;
	int x,y;
	int v;
	
	node(int x, int y): l(0),r(0),x(x),y(y),v(0) {}
};
node *trees[MAXN];

void dfs(int f, int t)
{
	pp[t] = f;
	if (t) lv[t] = lv[f]+1;
	sz[t]=1;
	for (auto i:e[t])
		if (i!=f)
		{
			dfs(t,i);
			sz[t]+=sz[i];
		}
		
	for (auto i:e[t])
		if (i!=f && 2*sz[i]>=sz[t])
		{
			path[t] = path[i];
			lenpath[path[t]]++;
		} else if (i!=f)
		{
			parent[path[i]] = i;
		}
	if (!path[t]) path[t] = numpaths++,lenpath[path[t]]++;
}

void itrees(node *t)
{
	if (t->x==t->y) return;
	int m = (t->x+t->y)/2;
	t->l = new node(t->x,m);
	t->r = new node(m+1,t->y);
	itrees(t->l);
	itrees(t->r);
}

void dfs2(int f, int t)
{
	if (f+1 && path[f]!=path[t]) lvpath[path[t]] = lv[path[f]]+1;
	for (auto i:e[t])
		if (i!=f) dfs2(t,i);
}

void init()
{
	lv[0]=0;
	dfs(-1,0);
	pp[0] = 0;
	lv[path[0]]=0;
	parent[path[0]] = 0;
	dfs2(-1,0);
	
	for (int i=1; i<numpaths; i++)
		trees[i] = new node(0,lenpath[i]-1),itrees(trees[i]);	
}

void upd(node *t,int pos,int k)
{
	if (t->x>pos) return;
	if (t->y<pos) return;
	
	if (t->x == t->y)
		t->v = k;
	else 
	{
		upd(t->l,pos,k);
		upd(t->r,pos,k);
		t->v=  max(t->l->v,t->r->v);
	}
}

void update(int x, int k)
{
	node *t;
	t = trees[path[x]];
	int pos = lv[x] - lv[parent[path[x]]];
	upd(t,pos,k);
}

int ans = 0;

void qq(node *t, int l, int r)
{
	if (t->x>r) return;
	if (t->y<l) return;
	
	if (l<=t->x && r>=t->y)
		ans = max(ans,t->v);
	else 
	{
		qq(t->l,l,r);
		qq(t->r,l,r);
	}
}

int query(int x, int y)
{
	ans = 0;
	
	while (true)
	{
		if (path[x]==path[y])
		{
			int lx = lv[x] - lv[parent[path[x]]];
			int ly = lv[y] - lv[parent[path[y]]];
			qq(trees[path[x]],min(lx,ly),max(lx,ly));
			break;
		} else 
		{
			if (lvpath[path[x]]<lvpath[path[y]]) swap(x,y);
			int lx;
			lx = lv[x] - lv[parent[path[x]]];
			qq(trees[path[x]],0,lx);
			x = parent[path[x]];
			x = pp[x];
		}
	}
	
	return ans;
}

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

int main()
{
	int m;
	fin>>n>>m;
	
	for (int i=0; i<n; i++)
		fin>>initial[i];
		
	for (int i=0; i<n-1; i++)
	{
		int x,y;
		fin>>x>>y;
		x--,y--;
		e[x].push_back(y);
		e[y].push_back(x);
	}		
	
	init();
	
	for (int i=0; i<n; i++)
		update(i,initial[i]);
	
	for (int i=0; i<m; i++)
	{
		int cod,x,y;
		fin>>cod>>x>>y;
		if (!cod) update(x-1,y);
		else 
		{
			int d =query(x-1,y-1); 
			fout<<d<<'\n'; 
		}
	}
	
	return 0;
}