Cod sursa(job #969311)

Utilizator dropsdrop source drops Data 4 iulie 2013 02:00:06
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.16 kb
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <bitset>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <ctime>
#include <string>
#include <cstring>
#include <iomanip>
#include <algorithm>
using namespace std;
ifstream ff("heavypath.in");
ofstream gg("heavypath.out");
#define nmax 100001
#define inf 0x3f3f3f3f
vector<int> vv[nmax], oo[nmax], bb[nmax];
int s, a, b, n, m, aa[nmax], ll[nmax], pp[nmax], rr[nmax], tt[nmax], kk[nmax];
bool ww[nmax];

void dfs(int x,int r){
	int y, k=-1, l=vv[x].size();
	ww[x]=1;
	kk[x]=r;
	for(int i=0;i<l;i++){
		y=vv[x][i];
		if(!ww[y]){
			dfs(y,r+1);
			if(k==-1 || rr[y]>rr[k])k=y;
			tt[y]=x;
		}
		rr[x]+=rr[y];
	}
	if(k==-1){
		ll[0]++;
		ll[x]=ll[0];
		oo[ll[x]].push_back(x);
		rr[x]=1;
	} else {
		ll[x]=ll[k];
		oo[ll[x]].push_back(x);
	}
}

void upd(vector<int> &oo, int n, int l, int r){
    if(l==r){ oo[n]=b; } else {
        int m=(l+r)/2;
        if(a<=m)upd(oo, 2*n, l, m); else
            upd(oo, 2*n+1, m+1, r); 
        oo[n]=max(oo[2*n], oo[2*n+1]); }
}
 
void qry(vector<int> &oo, int n,int l,int r){
    if(a<=l&&r<=b){ s=max(s,oo[n]); } else {
        int m=(l+r)/2;
        if(a<=m)qry(oo, 2*n, l, m);
        if(b>m)qry(oo, 2*n+1, m+1, r); }
}
 
int main(){
	int o;
	ff >> n >> m;
	for(int i=1;i<=n;i++) ff >> aa[i];
	for(int i=1;i<n;i++){
		ff >> a >> b;
		vv[a].push_back(b);
		vv[b].push_back(a);
	}
	dfs(1,1);
	//for(int i=1;i<=n;i++) gg << tt[i] << " "; gg << "\n";
	for(int i=1;i<=n;i++){
		reverse(oo[i].begin(), oo[i].end());
		bb[i].resize((int)oo[i].size()*3);
	}
	for(int i=1;i<=n;i++)
	for(int j=0;j<(int)oo[i].size();j++) pp[oo[i][j]]=j+1;
	//for(int i=1;i<=n;i++) gg << kk[i] << " "; gg << "\n";
	
	for(int i=1;i<=n;i++){
		for(int j=0;j<(int)oo[i].size();j++){
			a=j+1; b=aa[oo[i][j]];
			upd(bb[i], 1, 1, oo[i].size());
		}
	}
	
	// int l=ll[0];
	// for(int i=1;i<=l;i++){
		// for(int j=0;j<bb[i].size();j++) gg << bb[i][j] << " ";
		// gg << "\n";
	// }
	int x, y, q;
	for(int i=1;i<=m;i++){
		ff >> o >> a >> b;
		if(o==0) {
			x=a; a=pp[a];
			upd(bb[ll[x]], 1, 1, oo[ll[x]].size()); 
		//	for(int i=1;i<bb[2].size();i++) cout << bb[2][i] << " "; cout <<"\n";
			} else {
			x=a, y=b, q=0;
			//gg << "Q( "<< x << " , " << y << " )\n";
			do{
				if(ll[x]==ll[y]){
					a=pp[x]; b=pp[y]; if(a>b) swap(a, b);
					//gg << "e " << a << " " << b << "\n";
					s=0;
					qry(bb[ll[x]], 1, 1, oo[ll[x]].size());
					q=max(q, s);
					x=y;
				} else {
					if(kk[ tt[oo[ll[x]][0]] ]>kk[ tt[oo[ll[y]][0]] ]){
						a=1; b=pp[x];
						//gg << "l " << a << " " << b << "\n";
						s=0;
						qry(bb[ll[x]], 1, 1, oo[ll[x]].size());
						q=max(q, s);
						x=tt[ oo[ll[x]][0] ];
					} else {
						a=1; b=pp[y];
						//gg << "r " << a << " " << b << "\n";
						s=0;
						qry(bb[ll[y]], 1, 1, oo[ll[y]].size());
						q=max(q, s);
						y=tt[ oo[ll[y]][0] ];
					}
				}
			}while(x!=y);
			gg << q << "\n";
		}
	}
	// int l=ll[0];
	// for(int i=1;i<=l;i++){
		// for(int j=0;j<bb[i].size();j++) gg << bb[i][j] << " ";
		// gg << "\n";
	// }
	return 0;
}