Cod sursa(job #1470532)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 11 august 2015 16:59:48
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.59 kb
#include <cstdio>
#include <vector>
#include <algorithm>

#define F first
#define S second

using namespace std;

const int Nmax = 100010;
const int DIM = 330;

int n , m , i , x , y , tip , node , sum , dim , lenght;
int left[Nmax] , right[Nmax];

int block[Nmax] , add_[DIM] , L[DIM];
pair < int , int > v[Nmax] , extreme[DIM] , El[DIM][DIM];

vector < int > g[Nmax];

void dfs(int node)
{
    v[++lenght] = {0 , node}; left[node] = lenght;

    for (auto &it : g[node])
        dfs(it);

    right[node] = lenght;
}

void restore(int ind)
{
    L[ind] = 0;
    for (int i = extreme[ind].F; i <= extreme[ind].S; ++i)
        El[ind][++L[ind]] = {v[i].F , v[i].S};
    sort(El[ind] + 1 , El[ind] + L[ind] + 1);
}

void init()
{
    int i , j , nr = 0; dim = 320;
    for (i = 1; i <= n; i += dim)
    {
        block[i] = (++nr);
        for (j = i; j <= min(i + dim - 1 , n); ++j)
            block[j] = block[i];
        extreme[nr] = {i , j - 1};
        restore(nr);
    }
}

void update(int L , int R , int Sum)
{
    int i;

    if (block[R] - block[L] <= 1)
    {
        for (i = L; i <= R; ++i)
            v[i].F += Sum;

        restore(block[L]);
        if (block[R] != block[L]) restore(block[R]);
    }
    else
    {
        for (i = block[L] + 1; i < block[R]; ++i)
            add_[i] += Sum;
        for (i = L; i <= extreme[block[L]].S; ++i)
            v[i].F += Sum;
        for (i = extreme[block[R]].F; i <= R; ++i)
            v[i].F += Sum;

        restore(block[L]); restore(block[R]);
    }
}

int query(int Sum)
{
    for (int ind = 1; ind <= block[n]; ++ind)
    {
        int i , step; int caut = Sum - add_[ind];

        for (step = 1; step < L[ind]; step <<= 1);

        for (i = 0; step; step >>= 1)
            if (i + step <= L[ind] && El[ind][i+step].F < caut)
                i += step;

        i++;
        if (i <= L[ind] && El[ind][i].F == caut)
            return El[ind][i].S;
    }

    return -1;
}

int main()
{
    freopen("arbore.in","r",stdin);
    freopen("arbore.out","w",stdout);

    scanf("%d %d", &n, &m);

    for (i = 1; i < n; ++i)
    {
        scanf("%d %d", &x, &y);
        g[x].push_back(y);
    }

    dfs(1);

    init();
    for (i = 1; i <= m; ++i)
    {
        scanf("%d", &tip);

        if (tip == 1)
        {
            scanf("%d %d", &node , &sum);
            update(left[node] , right[node] , sum);
        }
        else
        {
            scanf("%d", &sum);
            printf("%d\n", query(sum));
        }
    }

    return 0;
}