Cod sursa(job #1957098)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 7 aprilie 2017 12:36:06
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.1 kb
#include <bits/stdc++.h>

using namespace std;

#define FILE_IO

int BLOCK_SIZE, K;

int N, Q;
vector <int> edg[100005];
int I, itv[100005][2];
int nd[100005];
int vl[100005];

bitset <1000005> bts[355];
int add[355];
int mrs[355];
bool mrsUpdated = true;

void DFS(int nod, int fth)
{
    itv[nod][0] = ++I;
    nd[I] = nod;

    for(auto nxt: edg[nod])
    {
        if(nxt == fth)  continue;
        DFS(nxt, nod);
    }

    itv[nod][1] = I;
}

void updateBlock(int id, int lft, int rgt, int val)
{
    int st = id * BLOCK_SIZE;
    int dr = (id + 1) * BLOCK_SIZE;
    for(int i = st; i < dr; i++)
        bts[id][ vl[i] ] = 0;
    for(int i = st; i < dr; i++)
    {
        if(lft <= i && i <= rgt)    vl[i] += val;
        bts[id][ vl[i] ] = 1;
    }
}

void update(int st, int dr, int val)
{
    int blkst = st / BLOCK_SIZE;
    int blkdr = dr / BLOCK_SIZE;

    if(blkst == blkdr)
    {
        updateBlock(blkst, st, dr, val);
        return;
    }

    if(blkst + 1 <= blkdr - 1)
    {
        mrs[blkst + 1] += val;
        mrs[blkdr] -= val;
        mrsUpdated = false;
    }

    updateBlock(blkst, st, (blkst + 1) * BLOCK_SIZE - 1, val);
    updateBlock(blkdr, blkdr * BLOCK_SIZE, dr, val);
}

int query(int val)
{
    if(!mrsUpdated)
    {
        for(int i = 0; i < K; i++)
            mrs[i] += mrs[i - 1];
        for(int i = 0; i < K; i++)
        {
            add[i] += mrs[i];
            mrs[i] = 0;
        }
        mrsUpdated = true;
    }

    for(int i = 0; i < K - 1; i++)
        if(val >= add[i + 1] && bts[i][ val - add[i + 1] ])
        {
            int st = i * BLOCK_SIZE;
            int dr = (i + 1) * BLOCK_SIZE;
            for(int j = st; j < dr; j++)
                if(vl[j] + add[i + 1] == val)
                    return nd[j];
        }
    for(int i = (K - 1) * BLOCK_SIZE; i < I; i++)
        if(vl[i] + add[K - 1 + 1] == val)
            return nd[i];
    return (-1);
}

int gint()
{
    char ch = getchar();
    while(ch < '0' || '9' < ch)
        ch = getchar();
    int x = 0;
    while('0' <= ch && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x;
}

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

    N = gint();
    Q = gint();
    for(int i = 1; i < N; i++)
    {
        int x, y;
        x = gint();
        y = gint();
        edg[x].push_back(y);
        edg[y].push_back(x);
    }

    I = -1;
    DFS(1, 0);
    I++;

    BLOCK_SIZE = (int)sqrt(I);
    K = I / BLOCK_SIZE + 1;
    for(int i = 0; i < K; i++)
        bts[i][0] = 1;

    while(Q--)
    {
        int op;
        op = gint();
        if(op == 1)
        {
            int nod, val;
            nod = gint();
            val = gint();
            update(itv[nod][0], itv[nod][1], val);
        }
        else
        {
            int val;
            val = gint();
            int ans = query(val);
            printf("%d\n", ans);
        }
    }

    return 0;
}