Cod sursa(job #1099816)

Utilizator superman_01Avramescu Cristian superman_01 Data 6 februarie 2014 12:43:00
Problema Arbore Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.45 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <bitset>
#include <cmath>

#define SQRTMAX 320
#define SMAX 1000005
#define NMAX 100005
#define pb push_back
#define get_max(a,b) ((a)>(b)?(a):(b))
#define get_min(a,b) ((a)<(b)?(a):(b))

using namespace std;

typedef vector < int > ::iterator IT ;

ifstream in ( "arbore.in" );
ofstream out ( "arbore.out" );

int N , M ;
vector < int > G[NMAX];
bitset < NMAX > used ;
bitset < SMAX > H[SQRTMAX];
int First[NMAX] , Last[NMAX] , Tree[NMAX] , List_Left[SQRTMAX] , List_Right[SQRTMAX];
int Number_Lists , List_Value[SQRTMAX] , V[NMAX];

void MakeEuler ( int node )
{
	used[node] = true ;
	Tree[++Tree[0]] = node ;
	First[node] = Tree[0];
	for ( IT it = G[node].begin() ; it != G[node].end() ; ++it )
		if ( ! used[ *it ] )
			MakeEuler(  *it );
	Last[node] = Tree[0];
}

void MakeBatog ( void )
{
	Number_Lists = int ( sqrt(N)) ;
	int List = 0  , i , j;
	for ( i = 1 ; i <= N ; ++List )
	{
		H[List][0] = 1 ;
		List_Left[List] = i ;
		List_Right[List] = i + Number_Lists - 1;
		i += Number_Lists;
	}
	Number_Lists = List;
    List_Right[Number_Lists-1] = N ;
}

void MakeMarsLike ( int start , int finish , int val )
{
	int i , j ;
	for ( i = 0 ; i < Number_Lists ; ++i )
	{
		if ( List_Right[i] < start or List_Left[i] > finish ) continue;
		if ( List_Left[i] >= start and List_Right[i] <= finish )
		{
			List_Value[i] += val;
			continue;
		}
		for ( j = List_Left[i] ; j <= List_Right[i] ; ++j )
		{
			H[i][V[j]] = 0;
			V[j] +=  List_Value[i] + val*(start<= j and j <= finish );
		}
		List_Value[i] = 0;
		for ( j = List_Left[i] ; j <= List_Right[i] ; ++j )
			H[i][V[j]] = 1 ;
	}
}

int Query ( int val )
{
	int i , j ;
	for ( i = 0 ; i < Number_Lists ; ++i )
	{
		if ( val < List_Value[i] ) continue;
		if ( H[i][val-List_Value[i] ] )
		{
			val -= List_Value[i];
			for ( j = List_Left[i] ; j <= List_Right[i] ; ++j )
				if ( V[j] == val )
					return Tree[j] ;
		}
	}
	return -1 ;
}

int main ( void )
{
	int i , j , x  , y , Type;
	in >> N >> M ;
	for ( i = 1 ; i < N ; ++i )
	{
		in >> x >> y ;
		G[x].pb(y);
		G[y].pb(x);
	}
	MakeEuler ( 1 );
	MakeBatog();
	for ( ; M > 0 ; --M )
	{
		in >> Type >> x  ;
		if ( Type == 1 )
		{
			in >> y ;
			MakeMarsLike( First[x] , Last[x] , y );
			continue;
		}
		out << Query ( x ) << "\n";
	}
	in.close();
	out.close();
	return 0 ;
}