Cod sursa(job #1451636)

Utilizator ZenusTudor Costin Razvan Zenus Data 17 iunie 2015 22:31:23
Problema Arbore Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.89 kb
#include <bits/stdc++.h>

using namespace std;

#define wN second.first
#define wP second.second
#define wI first

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

const int SSIZE = 317 + 10;
const int NSIZE = 100000 + 10;
const int MOD = 1007;

pair < int , int > p[NSIZE];
int add[SSIZE] , aux[NSIZE];
vector < pair < int , int > > iH[SSIZE][MOD];
vector < int > iB[SSIZE];
int N , Q , x , y , type , i , crt , block;
vector < int > g[NSIZE];

int wB(int i)
{
    return i / block;
}

int wiB(int i)
{
    return i % block;
}

void df(int node,int fa)
{
    p[node].first = ++crt;
    aux[crt] = node;

    for (int i=0;i<g[node].size();++i)
    {
        int to = g[node][i];

        if (to != fa) df(to,node);
    }

    p[node].second = crt;
}

void inH(int i)
{
    int crt = wB(i) , j = wiB(i);
    int line = iB[crt][j] % MOD;

    iH[crt][line].push_back({iB[crt][j] , i});
}

void outH(int i)
{
    int crt = wB(i) , j = wiB(i);
    int line = iB[crt][j] % MOD;
    vector < pair < int , int > > :: iterator it;

    for (it = iH[crt][line].begin() ; it < iH[crt][line].end() ; ++it)
    if ((*it) == make_pair(iB[crt][j] , i))
    {
        iH[crt][line].erase(it);
        return ;
    }
}

int findH(int x , int crt)
{
    int line = x % MOD , i;

    for (i = 0 ; i < iH[crt][line].size() ; ++i)
    if (iH[crt][line][i].first == x) return iH[crt][line][i].second;

    return -1;
}

void build()
{
    int i;

    for (i = 0 ; i < N ; ++i)
    {
        iB[wB(i)].push_back(0);
        inH(i);
    }
}

void update(int le,int ri,int x)
{
    int i , j1 , j2;

    if (le % block != 0)
    {
        j1 = wB(le) + 1;

        for (i = le ; i % block != 0 && i <= ri ; ++i)
        {
            outH(i);
            iB[wB(i)][wiB(i)] += x;
            inH(i);
        }

        if (wB(le) == wB(ri)) return ;
    } else j1 = wB(le);

    if ((ri + 1) % block != 0)
    {
        j2 = wB(ri) - 1;

        for (i = ri ; (i + 1) % block != 0 && i >= le ; --i)
        {
            outH(i);
            iB[wB(i)][wiB(i)] += x;
            inH(i);
        }

        if (wB(le) == wB(ri)) return ;
    } else j2 = wB(ri);

    for (i = j1 ; i <= j2 ; ++i)
    add[i] += x;
}

int query(int x)
{
    int i , j1 , j2 , k , f;

    for (i = 0 ; i <= wB(N - 1) ; ++i)
    {
        f = findH(x - add[i] , i);
        if (f != -1) return aux[f];
    }

    return -1;
}

int main()
{

fin >> N >> Q;
block = (int)sqrt(1.0 * N);

for (i=1;i<N;++i)
{
    fin >> x >> y;
    g[x].push_back(y);
    g[y].push_back(x);
}

crt = -1;
df(1,0);
build();

for (i=1;i<=Q;++i)
{
    fin >> type;

    if (type == 1)
    {
        fin >> x >> y;
        update(p[x].first,p[x].second,y);
    }
    else
    {
        fin >> y;
        fout << query(y) << '\n';
    }
}

return 0;
}