Cod sursa(job #3341183)

Utilizator BuzdiBuzdugan Rares Andrei Buzdi Data 18 februarie 2026 12:47:34
Problema Arbore Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.98 kb
#include <bits/stdc++.h>
#define ll long long

using namespace std;

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

const int BLOCK = 316;
const int NMAX = 1e5;

int n, m, t;
unordered_map<int, int> mp[BLOCK + 1];
vector<int> g[NMAX + 1];
int in[NMAX + 1], out[NMAX + 1];
int a[NMAX + 1];
int lazy[BLOCK + 1];
int pos[NMAX + 1];

void DFS(int node, int dad = 0) {
    in[node] = ++t;
    pos[t] = node;
    for(int next_node : g[node]) {
        if(next_node != dad) {
            DFS(next_node, node);
        }
    }
    out[node] = t;
}

void update(int node, int x) {
    int left = in[node];
    int right = out[node];
    left--; right--; /// 0-indexing

    int block_left = left / BLOCK;
    int block_right = right / BLOCK;
    if(block_left == block_right) {
        for(int i = left; i <= right; i++) {
            mp[block_left][a[i]]--;
            if(!mp[block_left][a[i]]) {
                mp[block_left].erase(a[i]);
            }
            a[i] += x;
            mp[block_left][a[i]]++;
        }
        return;
    }

    /// Blocul din stanga
    for(int i = left; i <= (block_left + 1) * BLOCK - 1; i++) {
        assert(i < n);
        mp[block_left][a[i]]--;
        if(!mp[block_left][a[i]]) {
            mp[block_left].erase(a[i]);
        }
        a[i] += x;
        mp[block_left][a[i]]++;
    }

    /// Blocurile din mijloc
    for(int i = block_left + 1; i <= block_right - 1; i++) {
        lazy[i] += x;
    }

    /// Blocul din dreapta
    for(int i = block_right * BLOCK; i <= right; i++) {
        assert(i < n);
        mp[block_right][a[i]]--;
        if(!mp[block_right][a[i]]) {
            mp[block_right].erase(a[i]);
        }
        a[i] += x;
        mp[block_right][a[i]]++;
    }
}

int query(int x) {
    for(int i = 0; i <= BLOCK; i++) {
        if(mp[i].count(x - lazy[i]) > 0) {
            for(int j = i * BLOCK; j <= min(n - 1, (i + 1) * BLOCK - 1); j++) {
                if(a[j] == x - lazy[i]) {
                    return pos[j] + 1;
                }
            }
            assert(false);
//            cout << i << ' ' << lazy[i] << ' ' << x << '\n';
//            for(int j = i * BLOCK; j <= min(n - 1, (i + 1) * BLOCK - 1); j++) {
//                cout << a[j] << ' ';
//            }
//            exit(0);
        }
    }
    return -1;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    fin >> n >> m;
    for(int i = 1; i <= n - 1; i++) {
        int a, b;
        fin >> a >> b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    DFS(1);

    for(int i = 1; i <= m; i++) {
        int type;
        fin >> type;
        if(type == 1) {
            int node, x;
            fin >> node >> x;
            update(node, x);
        }
        else {
            int x;
            fin >> x;
            fout << query(x) << '\n';
        }
    }
    return 0;
}

/// NU UITA SA FACI 0-INDEXING