Cod sursa(job #2072857)

Utilizator antanaAntonia Boca antana Data 22 noiembrie 2017 12:40:07
Problema Arbore Scor 35
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.41 kb
#include <bits/stdc++.h>

using namespace std;

FILE *fin = fopen( "arbore.in", "r" );
FILE *fout= fopen( "arbore.out","w" );

const int maxv    = 1e6 + 1;
const int maxn    = 1e5 + 5;
const int Bsize   = 100;
const int buckets = 1010;
const int bufsize = (1<<17);

char buf[bufsize];
int pos = bufsize;

inline char getChar() {
    if (pos == bufsize)
        pos = 0, fread( buf, 1, bufsize, fin );
    return buf[ pos++ ];
}

inline int getInt() {
    int nr = 0;
    char c;
    c = getChar();
    while (!isdigit(c))
        c = getChar();
    while (isdigit(c)) {
        nr = nr*10 + c-'0';
        c = getChar();
    }
    return nr;
}

vector < int > G[maxn];
pair < int, int > seq[maxn];
unordered_map < int, int > Map[buckets];

int n, m, k, v[maxn], values[maxn], lazy[buckets], where[maxn];

void dfs( int node, int dad ) {
    v[ ++k ] = node;
    seq[ node ].first = k;
    for (int son: G[ node ])
        if (son != dad)
            dfs( son, node );
    seq[ node ].second = k;
}

inline void eraseFromMap( int idx, int value ) {
    Map[ idx ][ value ]--;
    if (Map[ idx ][ value ] == 0)
        Map[ idx ].erase( value );
}

inline void addInMap( int idx, int value ) {
    Map[ idx ][ value ]++;
}

inline void update( int left, int right, int value ) {
    int pos, stopLeft, startRight;
    if (left == (where[ left ] - 1) * Bsize + 1)
        pos = left;
    else
        pos = where[ left ] * Bsize + 1;

    stopLeft = min( right, pos - 1 );

    for (; pos + Bsize - 1 <= right; pos += Bsize)
        lazy[ where[ pos ] ] += value;

    for (int i = left; i <= stopLeft; i++) {
        eraseFromMap( where[ i ], values[ i ] );
        values[ i ] += value;
    }

    for (int i = left; i <= stopLeft; i++)
        addInMap( where[ i ], values[ i ] );

    if (pos - Bsize == right)
        return;

    startRight = max( stopLeft + 1, (where[ right ] - 1) * Bsize + 1 );
    for (int i = startRight; i <= right; i++) {
        eraseFromMap( where[ i ], values[ i ] );
        values[ i ] += value;
    }

    for (int i = startRight; i <= right; i++)
        addInMap( where[ i ], values[ i ] );
}

int searchBucket( int idx, int value ) {
    int left = (idx - 1) * Bsize + 1, right = min( n, idx * Bsize );
    for (int i = left; i <= right; i++)
        if (values[ i ] == value)
            return v[ i ];

    return -1;
}

int query( int value ) {
    for (int i = 1; i <= n; i += Bsize) {
        if (Map[ where[ i ] ].find( value - lazy[ where[ i ] ] ) != Map[ where[ i ] ].end())
            return searchBucket( where[ i ], value - lazy[ where[ i ] ] );
    }

    return -1;
}

int main()
{
    int op, x, y;

    n = getInt();
    m = getInt();

    for (int i = 1; i < n; i++) {
        x = getInt();
        y = getInt();
        G[ x ].push_back( y );
        G[ y ].push_back( x );
    }

    for (int i = 1; i <= n; i++) {
        where[ i ] = ( i + Bsize - 1) / Bsize;
        Map[ where[ i ] ][ 0 ]++;
    }

    dfs( 1, 0 );

    for (int i = 1; i <= m; i++) {
        op = getInt();
        if (op == 1) {
            x = getInt();
            y = getInt();
            update( seq[ x ].first, seq[ x ].second, y );
        }
        else {
            x = getInt();
            fprintf( fout, "%d\n", query( x ) );
        }
    }

    fclose( fin );
    fclose( fout);

    return 0;
}