Cod sursa(job #1470593)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 11 august 2015 17:57:00
Problema Arbore Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.69 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <bitset>

#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];

bitset < 1000010 > Hash[DIM];

bool marked[Nmax];

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

    for (auto &it : g[node])
        if (!marked[it])
            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},
        Hash[ind][v[i].F] = 1;
    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 caut = Sum - add_[ind];

        if (caut < 0) continue;

        if (Hash[ind][caut] != 0)
        {
            for (int i = 1; i <= L[ind]; ++i)
                if (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);
        g[y].push_back(x);
    }

    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;
}