Cod sursa(job #1278092)

Utilizator geniucosOncescu Costin geniucos Data 28 noiembrie 2014 15:03:52
Problema Arbore Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.37 kb
#include<cstdio>
#include<vector>
#include<bitset>

using namespace std;

int tip, sq, N, M, Nr, ap[100009], v[100009], unde[100009], dr[100009], de_unde[100009], A[100009], left[320], right[320], buc[320];
bitset < 1000001 > poate[320];

vector < int > muchie[100009];

void dfs (int nod)
{
    ap[nod] = 1;
    v[++Nr] = nod;
    unde[nod] = Nr;
    for (vector < int > :: iterator it = muchie[nod].begin(); it != muchie[nod].end(); it++)
        if (ap[*it] == 0)
            dfs (*it);
    dr[nod] = Nr;
}

void Refresh (int bucata, bool bit)
{
    for (int i = left[bucata]; i <= right[bucata]; i++)
        poate[bucata][A[i]] = bit;
}

void U (int st, int dr, int val)
{
    if (de_unde[st] == de_unde[dr])
    {
        Refresh (de_unde[st], 0);
        for (int i=st; i<=dr; i++)
            A[i] += val;
        Refresh (de_unde[st], 1);
        return ;
    }
    Refresh (de_unde[st], 0);
    Refresh (de_unde[dr], 0);
    for (int i=st; i<=right[de_unde[st]]; i++)
        A[i] += val;
    for (int i=left[de_unde[dr]]; i<=dr; i++)
        A[i] += val;
    Refresh (de_unde[st], 1);
    Refresh (de_unde[dr], 1);
    for (int bucata = de_unde[st] + 1; bucata < de_unde[dr]; bucata ++)
        buc[bucata] += val;
}

int Q (int sum)
{
    for (int i=1; i<=Nr; i++)
        if (sum >= buc[i] && poate[i][sum - buc[i]])
        {
            for (int j=left[i]; j<=right[i]; j++)
                if (buc[i] + A[j] == sum)
                    return v[j];
        }
    return -1;
}

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

scanf ("%d", &N);
scanf ("%d", &M);
for (int i=1; i<N; i++)
{
    int X, Y;
    scanf ("%d %d", &X, &Y);
    muchie[X].push_back(Y);
    muchie[Y].push_back(X);
}

dfs (1);

for (int i=1; i*i <= Nr; i++)
    sq ++;
Nr = 0;
for (int i=1; (i-1)*sq+1 <= N; i++)
{
    Nr ++;
    left[i] = (i-1)*sq+1;
    for (int j=left[i]; j <= left[i] + sq - 1 && j <= N; j++)
    {
        right[i] = j;
        de_unde[j] = i;
    }
}

for (int i=1; i<=Nr; i++)
    poate[i][0] = 1;

while (M)
{
    M --;
    scanf ("%d", &tip);
    if (tip == 1)
    {
        int X, Y;
        scanf ("%d %d", &X, &Y);
        U (unde[X], dr[X], Y);
    }
    else
    {
        int X;
        scanf ("%d", &X);
        printf ("%d\n", Q(X));
    }
}
return 0;
}