Cod sursa(job #2438242)

Utilizator AndreiStanescuAlloys Nokito AndreiStanescu Data 11 iulie 2019 20:51:37
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.63 kb
#include<bits/stdc++.h>
using namespace std;

#define N 100001

struct treeNode
{
	int par; // Parent of this node
	int depth; // Depth of this node
	int size; // Size of subtree rooted with this node
	int pos_segbase; // Position in segment tree base
	int chain;
} node[N];


struct segmentTree
{
	int base_array[N], tree[6*N];
} s;


vector<int> G[N];

void dfs(int curr, int prev, int dep, int n)
{
	/* set parent of current node to predecessor*/
	node[curr].par = prev;
	node[curr].depth = dep;
	node[curr].size = 1;

	/* for node's every child */
	vector<int>::iterator j;
	for(j=G[curr].begin();j!=G[curr].end();j++)
	{
		if ( (*j)!=curr && (*j)!=node[curr].par )
		{
			/* set deeper end of the Edge as this child*/

			/* do a DFS on subtree */
			dfs(*j, curr, dep+1, n);

			/* update subtree size */
			node[curr].size+=node[*j].size;
		}
	}
}

int v[N];


void hld(int curr_node,  int *edge_counted, int *curr_chain,
		int n, int chain_heads[])
{

	if (chain_heads[*curr_chain]==-1)
		chain_heads[*curr_chain] = curr_node;


	node[curr_node].chain = *curr_chain;



	node[curr_node].pos_segbase = *edge_counted;


	s.base_array[(*edge_counted)++] = v[curr_node];


	int spcl_chld = -1;
	vector<int>::iterator j;
	for(j=G[curr_node].begin();j!=G[curr_node].end();j++)
	if ( (*j)!=curr_node && (*j)!=node[curr_node].par )
		if (spcl_chld==-1 || node[spcl_chld].size < node[*j].size)
		spcl_chld = (*j);


	if (spcl_chld!=-1)
	hld(spcl_chld,  edge_counted, curr_chain, n, chain_heads);


	for(j=G[curr_node].begin();j!=G[curr_node].end();j++)
	if ( (*j)!=curr_node && (*j)!=node[curr_node].par && (*j)!=spcl_chld)
	{
		(*curr_chain)++;
		hld(*j,  edge_counted, curr_chain, n, chain_heads);
	}
}


int construct_ST(int ss, int se, int si)
{

	if (ss == se-1)
	{
		s.tree[si] = s.base_array[ss];
		return s.base_array[ss];
	}


	int mid = (ss + se)/2;
	s.tree[si] = max(construct_ST(ss, mid, si*2),
					construct_ST(mid, se, si*2+1));
	return s.tree[si];
}

int update_ST(int ss, int se, int si, int x, int val)
{

	if(ss > x || se <= x);

	else if(ss == x && ss == se-1)s.tree[si] = val;

	else
	{
		int mid = (ss + se)/2;
		s.tree[si] = max(update_ST(ss, mid, si*2, x, val),
						update_ST(mid, se, si*2+1, x, val));
	}

	return s.tree[si];
}


int LCA(int u, int v, int n)
{

	int LCA_aux[n+5];


	if (node[u].depth < node[v].depth)
	swap(u, v);

	memset(LCA_aux, -1, sizeof(LCA_aux));

	while (u!=-1)
	{
		LCA_aux[u] = 1;
		u = node[u].par;
	}

	while (v)
	{
		if (LCA_aux[v]==1)break;
		v = node[v].par;
	}

	return v;
}


int RMQUtil(int ss, int se, int qs, int qe, int index)
{
	if (qs <= ss && qe >= se-1)
		return s.tree[index];


	if (se-1 < qs || ss > qe)
		return -1;


	int mid = (ss + se)/2;
	return max(RMQUtil(ss, mid, qs, qe, 2*index),
			RMQUtil(mid, se, qs, qe, 2*index+1));
}


int RMQ(int qs, int qe, int n)
{
	// Check for erroneous input values
	if (qs < 0 || qe > n || qs > qe)
	{
		printf("Invalid Input");
		return -1;
	}

	return RMQUtil(0, n, qs, qe, 1);
}


int crawl_tree(int u, int v, int n, int chain_heads[])
{
	int chain_u, chain_v = node[v].chain, ans = 0;

	while (true)
	{
		chain_u = node[u].chain;
		if (chain_u==chain_v)
		{
			if (u==v); //trivial
			else
			ans = max(RMQ(node[v].pos_segbase+1, node[u].pos_segbase, n),
						ans);
			break;
		}

		else
		{
			ans = max(ans,
					RMQ(node[chain_heads[chain_u]].pos_segbase,
						node[u].pos_segbase, n));

			u = node[chain_heads[chain_u]].par;
		}
	}

	return ans;
}


int maxNode(int u, int v, int n, int chain_heads[])
{
	int lca = LCA(u, v, n);
	int ans = max(crawl_tree(u, lca, n, chain_heads),
				crawl_tree(v, lca, n, chain_heads));
	return ans;
}

// driver function
int main()
{
	int n,m,i,a,b,t;
	ifstream fin("heavypath.in");
	ofstream fout("heavypath.out");
	fin>>n>>m;
	for(i=1;i<=n;i++)
        fin>>v[i];
    for(i=1;i<n;i++)
    {
        fin>>a>>b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
	int root = 1, parent_of_root=-1, depth_of_root=0;
	dfs(root, parent_of_root, depth_of_root, n);
	int chain_heads[N];
	memset(chain_heads, -1, sizeof(chain_heads));
	int edge_counted = 0;
	int curr_chain = 0;
	hld(root, &edge_counted, &curr_chain, n, chain_heads);
	construct_ST(0, edge_counted, 1);
	//cout<<s.tree[1];

	for(i=1;i<=m;i++)
    {
        fin>>t>>a>>b;
        if(!t)
            update_ST(0,n,1,node[a].pos_segbase,b);
        if(t==1)
            fout<<maxNode(a,b,n,chain_heads)<<'\n';
    }
    fin.close();
    fout.close();
	return 0;
}