Cod sursa(job #1546472)

Utilizator algebristulFilip Berila algebristul Data 8 decembrie 2015 03:47:07
Problema Arbore Scor 65
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.42 kb
#include <cstdio>
#include <vector>
#include <cmath>
#include <bitset>

using namespace std;

const int NMAX = 100005;
const int SMAX = 1000005;

struct smen {
    vector<bool> S;
    int inc;
};

vector<int> A[NMAX];
int v[2*NMAX+1];
int F[NMAX];
int L[NMAX];
int Nod[NMAX*2+1];
int n, m;
int pos, sq;
smen bucati[501];

inline int smen_pos(int x) {
    return (x - 1) / sq;
}

void dfs(int x, int parent) {
    F[x] = ++pos;
    L[x] = pos;
    Nod[pos] = x;
    for (const auto& y: A[x]) {
        if (y == parent)
            continue;
        dfs(y, x);
        L[x] = ++pos;
        Nod[pos] = x;
    }
}

void update_smen(int smen, int val) {
    bucati[smen].inc += val;
}

void update_brut(int smen, int l, int r, int val) {
    bucati[smen].S.clear();
    for (int i = l; i <= r; i++) {
        v[i] += val;
    }
    for (int i = max(smen * sq, 1); i <= min(smen * sq + sq - 1, pos); i++) {
        if (v[i] < SMAX)
            bucati[smen].S[v[i]] = 1;
    }
}

void update(int l, int r, int val) {
    int l_smen = smen_pos(l);
    int r_smen = smen_pos(r);
    if (l_smen == r_smen) {
        update_brut(l_smen, l, r, val);
        return;
    }

    update_brut(l_smen, l, l_smen * sq + sq - 1, val);
    for (int i = l_smen + 1; i < r_smen; i++) {
        update_smen(i, val);
    }
    update_brut(r_smen, r_smen * sq, r, val);
}

int query(int s) {
    for (int i = 0; i <= smen_pos(pos); i++) {
        if (s < bucati[i].inc)
            continue;

        if (bucati[i].S[s - bucati[i].inc]) {
            int l = max(i * sq, 1);
            int r = min(l + sq - 1, pos);

            for (int j = l; j <= r; j++) {
                if (v[j] == s - bucati[i].inc) {
                    return Nod[j];
                }
            }
        }
    }

    return -1;
}

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

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

    dfs(1, 0);
    sq = sqrt(pos);

    for (int i = 0; i <= smen_pos(pos); i++) {
        bucati[i].S.resize(SMAX, 0);
    }

    for (int i = 0; i < m; i++) {
        int op, p, s;
        scanf("%d", &op);
        if (op == 1) {
            scanf("%d %d", &p, &s);
            update(F[p], L[p], s);
        }
        if (op == 2) {
            scanf("%d", &s);
            printf("%d\n", query(s));
        }
    }


    return 0;
}