Cod sursa(job #3248683)

Utilizator Allie28Radu Alesia Allie28 Data 12 octombrie 2024 17:22:49
Problema Arbore Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.07 kb
#include <fstream>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <unordered_map>
#include <climits>

using namespace std;

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

const int LMAX = 100005;
const int NMAX = 350;

vector<int> L[LMAX], euler;
int sons[LMAX], poz[LMAX], lft[NMAX], rght[NMAX];
long long sum_buc[NMAX], sum_elem[LMAX], y, x;
unordered_map<int, int> mymap[NMAX];

void dfs(int node) {
    poz[node] = (int)euler.size();
    euler.push_back(node);
    sons[node] = (int)L[node].size();
    for (int vec : L[node]) {
        dfs(vec);
        sons[node] += sons[vec];
    }
}

void add(int l, int r, int b) {
    for (int i = l; i <= r; i++) {
        mymap[b][sum_elem[i]]--;
        sum_elem[i] += y;
        mymap[b][sum_elem[i]]++;
    }
}

int main() {
    int n, m, i, c;
    fin>>n>>m;
    for (i = 1; i < n; i++) {
        fin>>x>>y;
        L[x].push_back(y);
    }
    //liniarizez
    dfs(1);
    //impart in bucati de radical
    int rd, cnt;
    rd = sqrt(n);
    cnt = 0;
    for (i = 0; i < n; i++) {
        if (i % rd == 0) { //incepe o bucata noua
            lft[i/rd] = i;
            cnt++; //creste nr de bucati
        }
        if (i % rd == rd - 1 || i == n - 1) { //se termina o bucata
            rght[i/rd] = i;
        }
        mymap[i/rd][0]++;
    }
//    for (i = 0; i < n; i++) {
//        fout<<euler[i]<<" ";
//    }
//    fout<<"\n";
//    for (i = 1; i <= n; i++) {
//        fout<<"poz lui "<<i<<" este "<<poz[i]<<"\n";
//    }
//    for (i = 0; i < cnt; i++) {
//        fout<<lft[i]<<" "<<rght[i]<<endl;
//    }
    while (m--) {
        fin>>c;
        if (c == 1) { //update
            fin>>x>>y; //angajatii lui x primesc y
            int cs, cd, b1, b2;
            cs = poz[x];
            b1 = cs/rd; //bucata 1
            cd = poz[x] + sons[x];
            b2 = cd/rd; //bucata 2
            if (b1 == b2) { //din aceeasi bucata
                add(cs, cd, b1);
            }
            else {
                add(cs, rght[b1], b1);
                for (i = b1 + 1; i < b2; i++) {
                    sum_buc[i] += y;
                }
                add(lft[b2], cd, b2);
            }

        }
        else { //query
            fin>>x;
            int b = -1;
            for (i = 0; i < cnt && b == -1; i++) { //trec prin toate bucatile
                if (mymap[i][x - sum_buc[i]]) {
                    b = i;
                }
            }
            if (b != -1) {
                i = lft[b];
                while (i <= rght[b] && (sum_elem[i] + sum_buc[b]) != x) {
                    i++;
                }
                fout<<euler[i];
            }
            else fout<<b;
            fout<<"\n";
        }
//        for (i = 0; i < n; i++) {
//            fout<<sum_elem[i]<<" ";
//        }
//        fout<<endl;
//        for (i = 0; i < cnt; i++) {
//            fout<<sum_buc[i]<<" ";
//        }
//        fout<<endl;
    }

    fin.close();
    fout.close();
    return 0;
}