Cod sursa(job #1970053)

Utilizator pas.andreiPopovici Andrei-Sorin pas.andrei Data 18 aprilie 2017 20:32:22
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.81 kb
#include <bits/stdc++.h>
#define NMAX 100005
#define pb push_back

using namespace std;

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

bool viz[NMAX];
int sub[NMAX],whichpath[NMAX],dimpath[NMAX],pathdepth[NMAX],pathfather[NMAX];
int depth[NMAX],nrpaths,aint[4*NMAX],val[NMAX],pozpath[NMAX];
vector<int> G[NMAX],P[NMAX];

void DFS(int x) {
	sub[x]=viz[x]=1;
	int care=0;

	sub[0]=-1;
	for(auto it:G[x]) {
		if(viz[it]) continue;

		depth[it]=depth[x]+1;
		DFS(it);
		sub[x]+=sub[it];

		if(sub[care]<sub[it]) care=it;
	}

	if(G[x].size()==1 && x!=1) {
		P[++nrpaths].pb(x);
		dimpath[nrpaths]=1;
		whichpath[x]=nrpaths;
		return;
	}

	whichpath[x]=whichpath[care];
	dimpath[whichpath[x]]++;
	P[whichpath[x]].pb(x);

	for(auto it:G[x]) {
		if(it==care || depth[it]<depth[x]) continue;

		pathfather[whichpath[it]]=x;
		pathdepth[whichpath[it]]=depth[x];
	}
}

void build(int nod, int st, int dr, int decalaj, int path) {
	if(st==dr) {
		aint[nod+decalaj]=val[P[path][st-1]];
		return;
	}

	int fs=nod*2,mid=(st+dr)/2;
	build(fs,st,mid,decalaj,path);
	build(fs+1,mid+1,dr,decalaj,path);

	aint[nod+decalaj]=max(aint[fs+decalaj],aint[fs+decalaj+1]);
}

void update(int nod, int st, int dr, int poz, int val, int decalaj) {
	if(st==dr) {
		aint[nod+decalaj] = val;
		return;
	}

	int fs=nod*2,mid=(st+dr)/2;
	if(poz<=mid) update(fs,st,mid,poz,val,decalaj);
	else update(fs+1,mid+1,dr,poz,val,decalaj);

	aint[nod + decalaj]=max(aint[fs+decalaj],aint[fs+decalaj+1]);
}

int query(int nod, int st, int dr, int qst, int qdr, int decalaj) {
	if(qst<=st && dr<=qdr)
		return aint[nod+decalaj];

	int fs=nod*2,mid=(st+dr)/2,res=0;
	if(qst<=mid) res=max(res,query(fs,st,mid,qst,qdr,decalaj));
	if(mid<qdr) res=max(res,query(fs+1,mid+1,dr,qst,qdr,decalaj));

	return res;
}

int main() {
	int n,i,t,x,y,m,ans;

	fin>>n>>m;

	for(i=1;i<=n;++i) fin>>val[i];
	for(i=1;i<n;++i) {
		fin>>x>>y;
		G[x].pb(y);
		G[y].pb(x);
	}

	depth[1]=1;
	DFS(1);
	for(i=1;i<=nrpaths;++i) {
		reverse(P[i].begin(),P[i].end());

		pozpath[i]=pozpath[i-1]+4*dimpath[i-1];
		build(1,1,dimpath[i],pozpath[i],i);
	}

	for(i=1;i<=m;++i) {
		fin>>t>>x>>y;

		if(t==0)
			update(1,1,dimpath[whichpath[x]],depth[x]-pathdepth[whichpath[x]],y,pozpath[whichpath[x]]);
		else {
			ans=0;
			while(1) {
				if(whichpath[x]==whichpath[y]) {
					if(depth[x]>depth[y]) swap(x,y);

					ans=max(ans,query(1,1,dimpath[whichpath[x]],depth[x]-pathdepth[whichpath[x]],depth[y]-pathdepth[whichpath[y]],pozpath[whichpath[x]]));
					break;
				}

				if(pathdepth[whichpath[x]]<pathdepth[whichpath[y]]) swap(x,y);
				ans=max(ans,query(1,1,dimpath[whichpath[x]],1,depth[x]-pathdepth[whichpath[x]],pozpath[whichpath[x]]));
				x=pathfather[whichpath[x]];
			}

			fout<<ans<<'\n';
		}
	}
}