Cod sursa(job #3304231)

Utilizator Cyb3rBoltSbora Ioan-David Cyb3rBolt Data 21 iulie 2025 23:16:35
Problema Arbore Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.59 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("arbore.in");
ofstream fout("arbore.out");
const int DIM = 1e5;
int n, tt, first[DIM + 3], last[DIM + 3], maxFirst = 0;
vector<int> muchii[DIM + 3];
int euler[DIM + 3], cntEuler = 0;

struct Iris {
    vector<pair<int, int>> v; ///first = suma ; second = index
}aint[4 * (2 * DIM + 1) + 3];
int lazy[4 * (2 * DIM + 1) + 3];

inline void dfs(int nod, int parent) {
    euler[++cntEuler] = nod;
    if(first[nod] == 0) first[nod] = cntEuler, maxFirst = max(maxFirst, cntEuler);
    last[nod] = cntEuler;
    for(int vecin : muchii[nod]) {
        if(vecin != parent) {
            dfs(vecin, nod);
            euler[++cntEuler] = nod;
            if(first[nod] == 0) first[nod] = cntEuler, maxFirst = max(maxFirst, cntEuler);
            last[nod] = cntEuler;
        }
    }
}

inline Iris combina(Iris a, Iris b) {
    Iris rez;
    int n = a.v.size(), m = b.v.size();
    int i = 0, j = 0;
    while(i < n && j < m) {
        if(a.v[i].first < b.v[j].first) rez.v.push_back(a.v[i++]);
        else if(b.v[j].first < a.v[i].first) rez.v.push_back(b.v[j++]);
        else rez.v.push_back(a.v[i++]), j++;
    }
    while(i < n) rez.v.push_back(a.v[i++]);
    while(j < m) rez.v.push_back(b.v[j++]);
    return rez;
}

inline void build(int nod, int st, int dr) {
    if(st == dr) aint[nod].v.push_back(make_pair(0, euler[st]));
    else {
        int mid = (st + dr) / 2;
        build(2 * nod, st, mid);
        build(2 * nod + 1, mid + 1, dr);
        aint[nod] = combina(aint[2 * nod], aint[2 * nod + 1]);
    }
}

inline void updateLazy(int nod, int st, int dr) {
    if(lazy[nod] != 0) {
        for(auto &i : aint[nod].v) i.first += lazy[nod];
        if(st != dr) {
            lazy[2 * nod] += lazy[nod];
            lazy[2 * nod + 1] += lazy[nod];
        }
        lazy[nod] = 0;
    }
}

inline void updateInterval(int nod, int st, int dr, int a, int b, int val) {
    updateLazy(nod, st, dr);
    if(a <= st && dr <= b) {
        for(auto &i : aint[nod].v) i.first += val;
        if(st != dr) {
            lazy[2 * nod] += val;
            lazy[2 * nod + 1] += val;
        }
    }
    else if(a > dr || b < st) return ;
    else {
        int mid = (st + dr) / 2;
        updateInterval(2 * nod, st, mid, a, b, val);
        updateInterval(2 * nod + 1, mid + 1, dr, a, b, val);
        updateLazy(2 * nod, st, mid);
        updateLazy(2 * nod + 1, mid + 1, dr);
        aint[nod] = combina(aint[2 * nod], aint[2 * nod + 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);
    build(1, 1, maxFirst);
    while(tt--) {
        int op; fin >> op;
        if(op == 1) {
            int poz, val; fin >> poz >> val;
            updateInterval(1, 1, cntEuler, first[poz], min(last[poz], maxFirst), val);
            //for(auto i : aint[1].v) cout << "sum = " << i.first << " index = " << i.second << '\n';
            //cout << '\n';
        }
        else {
            int val; fin >> val;
            int st = 0, dr = aint[1].v.size() - 1, sol = -1;
            while(st <= dr) {
                int mid = (st + dr) / 2;
                if(aint[1].v[mid].first == val) {
                    sol = aint[1].v[mid].second;
                    break;
                }
                else if(aint[1].v[mid].first < val) st = mid + 1;
                else dr = mid - 1;
            }
            fout << sol << '\n';
        }
    }

    return 0;
}