Cod sursa(job #2277613)

Utilizator b10nd3Oana Mancu b10nd3 Data 6 noiembrie 2018 16:59:47
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.51 kb
#include<iostream>
#include<fstream>
#include<algorithm>
#include<vector>

using namespace std;

#define NMAX 100010

int n, m, noLant;
int v[NMAX], niv[NMAX], card[NMAX], lant[NMAX], lDim[NMAX], lDad[NMAX], lNiv[NMAX], lPoz[NMAX], arbInt[NMAX*4];
bool viz[NMAX];
vector<int> G[NMAX], L[NMAX];



void df(int nod){
 
	vector<int>::iterator it;
	
	viz[nod] = true; 
	card[nod] = 1;
	int hn=-1;
	bool frunza = true;
	
	for(it=G[nod].begin(); it!=G[nod].end(); it++ ){
		
		if(viz[*it]) continue;
		frunza = false; 
		
		niv[*it] = niv[nod] + 1;
		
		df(*it);
		
		card[nod] += card[*it];
		if(hn == -1) hn = *it;
		else if(card[hn] < card[*it])
		   hn = *it;
	}
	
	if(frunza){ // => creaza lant nou
         ++noLant;
         lant[nod] = noLant;
		 lDim[noLant] = 1;
		 L[noLant].push_back(nod);
		 return;
	}
	
	lant[nod] = lant[hn];
	lDim[ lant[nod] ] ++;
	L[ lant[nod] ].push_back(nod);
	
	for(it=G[nod].begin(); it!=G[nod].end(); it++ ){
	     
		 if( (*it) == hn || niv[nod] > niv[*it] )
	        continue;
	        
	     lDad[ lant[*it] ] = nod;
		 lNiv[ lant[*it] ] = niv[nod];   
	}
	
}


void build( int nod, int left, int right, int decalaj, int lNo ){
	
	if(left == right){
		arbInt[decalaj + nod] = v[ L[lNo][left-1] ];
		return;
	}  
	
	int mid = (left + right)/2;
	build(nod*2,left, mid,decalaj,lNo);
	build(nod*2+1,mid+1,right,decalaj,lNo);
	
	arbInt[decalaj+nod] = max( arbInt[decalaj+2*nod], arbInt[decalaj+2*nod+1] );
}


void update(int nod, int left, int right, int poz, int decalaj, int val ){
	
	if(left==right){
		arbInt[decalaj + nod] = val;
		return;
	}
	
	int mid=(left+right)/2;
	if(poz <= mid) 
	   update(nod*2,left,mid,poz,decalaj,val);
	else
	   update(nod*2+1,mid+1,right,poz,decalaj,val);
	   	   
	arbInt[decalaj+nod] = max( arbInt[decalaj+2*nod], arbInt[decalaj+2*nod+1] ); 
}


int query(int nod, int left, int right, int x, int y, int decalaj){
	
	if( x <= left && right <= y)
	    return arbInt[decalaj + nod];
	
	int mid = (left+right)/2, rez = 0;  
	if(x <= mid )
	    rez =  max( rez , query(nod*2,left,mid,x,y,decalaj) ); 
	if(mid < y) 
	    rez =  max( rez , query(nod*2+1,mid+1,right,x,y,decalaj) );
		
    return rez; 
}


int main(){
 	FILE *in = fopen("heavypath.in","r"), *out = fopen("heavypath.out","w");
	int i,a,b,t,x,y,sol;
	
	//citire date
	fscanf(in,"%d %d",&n,&m);
	
	for(i=1; i<=n; i++)
	   fscanf(in,"%d",&v[i]);
	
	for(i=1; i<n; i++){
		fscanf(in,"%i%i",&a,&b);
		G[a].push_back(b);
		G[b].push_back(a);
	}
	
	
	//constructie lanturi
	niv[1] = 1;
	df(1);
	
	//constr Arbore Intervale din lanturi
	for(i=1; i<=noLant; i++){
		reverse(L[i].begin(),L[i].end());
		if(i>1)  lPoz[i] = lPoz[i-1] + lDim[i-1]*4;
		build(1, 1, lDim[i], lPoz[i], i);
	}
	
	while(m--){
		fscanf(in,"%i%i%i",&t,&x,&y);
		if(t==0)
		   update(1,1,lDim[lant[x]],niv[x]-lNiv[lant[x]],lPoz[lant[x]],y);
		else{
		   sol=0;
		   while(1){
		   	    
		   	    if(lant[x] == lant[y]){
		   	    	  if(niv[x] > niv[y])
		   	    	       swap(x,y);
		   	    	  sol = max(sol, query( 1, 1, lDim[lant[x]], niv[x] - lNiv[lant[x]], niv[y] - lNiv[lant[x]], lPoz[lant[x]] ) );
		   	    	  break;
				   }
				   
				 if( lNiv[lant[x]] < lNiv[lant[y]] )
				      swap(x,y);  
				 
				 sol = max(sol, query(1, 1, lDim[lant[x]], 1, niv[x] - lNiv[lant[x]], lPoz[lant[x]] ) );
				 
				 x = lDad[ lant[x] ];     
		   	    
		   }	
		   fprintf(out,"%d\n",sol);
		}
	}
	
	fclose(in), fclose(out);
	return 0;
}