Cod sursa(job #3359429)

Utilizator rares89_Dumitriu Rares rares89_ Data 27 iunie 2026 21:06:40
Problema Arbore Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.01 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 100000;
const int VMAX = 1000000;
const int B = 700;
const int NB = 150;
const int W = (VMAX + 64) / 64;

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

int n, m, timp, nb;
int tin[NMAX + 5], tout[NMAX + 5], euler[NMAX + 5];
int val[NMAX + 5], lazy[NB], id[NMAX + 5], st[NB], dr[NB];
int p[NMAX + 5], it[NMAX + 5];
vector<int> g[NMAX + 5];
unsigned long long has[NB][W];

void setbit(int b, int x) {
    has[b][x >> 6] |= 1ULL << (x & 63);
}

void clrbit(int b, int x) {
    has[b][x >> 6] &= ~(1ULL << (x & 63));
}

int getbit(int b, int x) {
    return (has[b][x >> 6] >> (x & 63)) & 1;
}

void rebuild(int b, int ok) {
    for(int i = st[b]; i <= dr[b]; i++) {
        if(val[i] <= VMAX) {
            if(ok) {
                setbit(b, val[i]);
            } else {
                clrbit(b, val[i]);
            }
        }
    }
}

void add(int l, int r, int x) {
    int a = id[l], b = id[r];

    if(a == b) {
        rebuild(a, 0);

        for(int i = l; i <= r; i++) {
            val[i] += x;
        }

        rebuild(a, 1);
        return;
    }

    rebuild(a, 0);

    for(int i = l; i <= dr[a]; i++) {
        val[i] += x;
    }

    rebuild(a, 1);

    rebuild(b, 0);

    for(int i = st[b]; i <= r; i++) {
        val[i] += x;
    }

    rebuild(b, 1);

    for(int i = a + 1; i < b; i++) {
        lazy[i] += x;
    }
}

int query(int x) {
    for(int b = 0; b < nb; b++) {
        int need = x - lazy[b];

        if(need < 0 || need > VMAX || !getbit(b, need)) {
            continue;
        }

        for(int i = st[b]; i <= dr[b]; i++) {
            if(val[i] == need) {
                return euler[i];
            }
        }
    }

    return -1;
}

int main() {
    fin >> n >> m;

    for(int i = 1; i < n; i++) {
        int a, b;
        fin >> a >> b;

        g[a].push_back(b);
        g[b].push_back(a);
    }

    stack<int> q;
    q.push(1);
    tin[1] = ++timp;
    euler[timp] = 1;

    while(!q.empty()) {
        int nod = q.top();

        if(it[nod] == (int)g[nod].size()) {
            tout[nod] = timp;
            q.pop();
            continue;
        }

        int fiu = g[nod][it[nod]++];

        if(fiu == p[nod]) {
            continue;
        }

        p[fiu] = nod;
        tin[fiu] = ++timp;
        euler[timp] = fiu;
        q.push(fiu);
    }

    nb = (n + B - 1) / B;

    for(int b = 0; b < nb; b++) {
        st[b] = b * B + 1;
        dr[b] = min(n, (b + 1) * B);

        for(int i = st[b]; i <= dr[b]; i++) {
            id[i] = b;
        }

        rebuild(b, 1);
    }

    while(m--) {
        int tip;
        fin >> tip;

        if(tip == 1) {
            int p, s;
            fin >> p >> s;

            add(tin[p], tout[p], s);
        } else {
            int s;
            fin >> s;

            fout << query(s) << "\n";
        }
    }

    return 0;
}