Cod sursa(job #3304331)

Utilizator Cyb3rBoltSbora Ioan-David Cyb3rBolt Data 22 iulie 2025 16:08:31
Problema Arbore Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.56 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("arbore.in");
ofstream fout("arbore.out");
const int DIM = 1e5;
int n, tt, poz[DIM + 3], copii[DIM + 3], maxFirst = 0;
vector<int> muchii[DIM + 3];
int euler[2 * DIM + 3], cntEuler = 0;
int blockSize, sumBlock[800], valSolo[2 * DIM + 3];
unordered_map<int, int> sumSolo[800]; ///pt fiecare bloc tin frecventa fiecare valori solo

inline void dfs(int nod, int parent) {
    euler[++cntEuler] = nod;
    poz[nod] = cntEuler;
    for(int vecin : muchii[nod]) {
        if(vecin != parent) {
            dfs(vecin, nod);
            copii[nod] += copii[vecin] + 1;
        }
    }
}

inline void update(int st, int dr, int val) {
    while(st <= dr && st % blockSize != 0) {
        if(valSolo[st] > 0) sumSolo[st / blockSize][valSolo[st]]--;
        valSolo[st] += val;
        sumSolo[st / blockSize][valSolo[st]]++;
        st++;
    }
    while(st + blockSize <= dr) {
        sumBlock[st / blockSize] += val;
        st += blockSize;
    }
    while(st <= dr) {
        if(valSolo[st] > 0) sumSolo[st / blockSize][valSolo[st]]--;
        valSolo[st] += val;
        sumSolo[st / blockSize][valSolo[st]]++;
        st++;
    }
}

inline int query(int st, int dr, int val) {
    while(st <= dr && st % blockSize != 0) {
        if(sumBlock[st / blockSize] + valSolo[st] == val) return euler[st];
        st++;
    }
    while(st + blockSize <= dr) {
        int need = val - sumBlock[st / blockSize];
        if(sumSolo[st / blockSize].find(need) != sumSolo[st / blockSize].end() && sumSolo[st / blockSize][need] > 0) {
            for(int i=st; i<=st+blockSize; i++)
                if(sumBlock[st / blockSize] + valSolo[i] == val) return euler[i];
        }
        st += blockSize;
    }
    while(st <= dr) {
        if(sumBlock[st / blockSize] + valSolo[st] == val) return euler[st];
        st++;
    }
    return -1;
}

int main()
{
    fin >> n >> tt;
    for(int i=1; i<n; i++) {
        int x, y; fin >> x >> y;
        muchii[x].push_back(y);
        muchii[y].push_back(x);
    }
    dfs(1, -1);
    blockSize = (int)sqrt(cntEuler);
    while(tt--) {
        int op; fin >> op;
        if(op == 1) {
            int nod, val; fin >> nod >> val;
            update(poz[nod], poz[nod] + copii[nod], val);
        }
        else {
            int val; fin >> val;
            fout << query(1, cntEuler, val) << '\n';
        }
        //for(int i=1; i<=maxFirst; i++) cout << sumBlock[i / blockSize] + valSolo[i] << " ";
        //cout << '\n';
    }

    return 0;
}