Pagini recente » Cod sursa (job #3189253) | Rating Bulutu Bianca (bulutubianca) | Cod sursa (job #385698) | Cod sursa (job #1606788) | Cod sursa (job #1248010)
/*
* Code by Spiromanul
*/
/*
* Pasul 1:Liniarizam ( dar atunci cand liniarizam,retinem pozitia pe care apare primul nod $nod si pozitia pe care apare ultimul nod $nod
* Pasul 2: Construim structul AINT cu campurile sum si maxim
* PROOF : sum este cat s-a primit pe intervalul [ st , dr ]
* PROOF : maxim este valoarea maxima primita de un nod din intervalul [ st , dr ]
* Pasul 3 : bagam arbori de intervale si luam 100
* Avantajul 1 : complexitate mai buna decat sqrt pe query ? da! log n pe query !
* Avantajul 2 : Memorie mai putina ca la solutiile in sqrt
* Avantajul 3 : Timp de executie mai mic
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <cassert>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <utility>
#include <ctime>
#include <bitset>
#define pb push_back
const char IN [ ] = "arbore.in" ;
const char OUT [ ] = "arbore.out" ;
const int MAX = 100014 ;
using namespace std ;
ifstream fin ( IN ) ;
ofstream fout ( OUT ) ;
struct AINT {
int sum , maxim ;
};
AINT arb [ MAX * 11 ] ;
vector < int > gr [ MAX ] ;
int stanga [ MAX ] , dreapta [ MAX ] , nr , lin [ ( MAX << 1 )+ 14 ] , sol ;
bitset < MAX > viz ;
void dfs ( int nod )
{
viz [ nod ] = 1 ;
lin [ ++ nr ] = nod ;
stanga [ nod ] = nr ;
for ( auto x : gr [ nod ] )
if ( viz [ x ] == 0 )
dfs ( x ) ;
lin [ ++ nr ] = nod ;
dreapta [ nod ] = nr ;
}
void update ( int nod , int st , int dr , int NODD , int add )
{
if ( stanga [ NODD ] <= st and dr <= dreapta [ NODD ] )
{
arb [ nod ].sum += add ;
arb [ nod ].maxim = arb [ nod ].sum + max ( arb [ nod << 1 ].maxim , arb [ nod << 1 | 1 ].maxim ) ;
return ;
}
else {
int mij = ( st + dr ) >> 1 ;
if ( stanga [ NODD ] <= mij )
update ( nod << 1 , st , mij , NODD , add ) ;
if ( dreapta [ NODD ] > mij )
update ( nod << 1 | 1 , mij + 1 , dr , NODD , add ) ;
arb [ nod ].maxim = arb [ nod ].sum + max ( arb [ nod << 1 ].maxim , arb [ nod << 1 | 1 ].maxim ) ;
}
}
void Query ( int nod , int st , int dr , int suma )
{
if ( sol >= 1 )
return ;
if ( arb [ nod ].sum == suma )
{
sol = lin [ st ] ;
return ;
}
if ( st < dr and arb [ nod ].sum < suma and arb [ nod ].maxim >= suma )
{
int mij = ( st + dr ) >> 1 ;
Query ( nod << 1 , st , mij , suma - arb [ nod ].sum ) ;
Query ( nod << 1 | 1 , mij + 1 , dr , suma - arb [ nod ].sum ) ;
}
}
int main ( )
{
int n , m ;
fin >> n >> m ;
for ( int i = 1 ; i < n ; ++ i )
{
int x , y ;
fin >> x >> y ;
gr [ x ].pb ( y ) ;
gr [ y ].pb ( x ) ;
}
dfs ( 1 ) ;
for ( ; m ; -- m )
{
int cod ;
fin >> cod ;
if ( cod == 1 )
{
int NODD , bag ;
fin >> NODD >> bag ;
//in loc sa bagam update pe n,bagam pe nr adica cardinalul reprezentarii euleriene
update ( 1 , 1 , nr , NODD , bag ) ;
}
else {
int sum ;
fin >> sum ;
sol = -1 ;
//in loc sa bagam query pe n,bagam pe nr adica cardinalul reprezentarii euleriene
Query ( 1 , 1 , nr , sum ) ;
fout << sol << '\n' ;
}
}
return 0 ;
}