Cod sursa(job #3147855)

Utilizator andrei_marciucMarciuc Andrei andrei_marciuc Data 27 august 2023 16:56:36
Problema Arbore Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <bits/stdc++.h>

using namespace std;

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

const int kS = 1e6;
const int kN = 1e5;
const int kB = 316;

int n, m;
vector<vector<int>> adj;

vector<int> preorder;
vector<int> tin, tout;
vector<int> cnt;
int cnt_b[1 + kN / kB];
bitset<1 + kS> ds[1 + kN / kB];

void dfs(int u = 0, int v = -1) {
    preorder.emplace_back(u);
    tin[u] = preorder.size() - 1;
    for(const auto &it: adj[u]) if(it != v) {
        dfs(it, u);
    }
    tout[u] = preorder.size() - 1;
}

void update(int u, int s) {
    int l = tin[u], r = tout[u];
    int b, llimit = (l + kB - 1) / kB * kB, ulimit = r / kB * kB;
    if(l < llimit) {
        b = l / kB;
        for(int i = l; i <= r && i < llimit; i++) {
            ds[b][cnt[i]] = 0;
        }
        while(l <= r && l < llimit) {
            cnt[l] += s;
            l++;
        }
        for(int i = llimit - kB; i < n && i < llimit; i++) {
            ds[b][cnt[i]] = 1;
        }
    }
    while(l < ulimit) {
        b = l / kB;
        cnt_b[b] += s;
        l += kB;
    }
    if(l <= r) {
        b = l / kB;
        for(int i = l; i <= r; i++) {
            ds[b][cnt[i]] = 0;
        }
        while(l <= r) {
            cnt[l] += s;
            l++;
        }
        for(int i = ulimit; i < n && i < ulimit + kB; i++) {
            ds[b][cnt[i]] = 1;
        }
    }
}

int query(int s) {
    for(int i = 0; i * kB <= n; i++) {
        if(cnt_b[i] <= s && ds[i][s - cnt_b[i]] == 1) {
            for(int j = i * kB; j < n && j < (i + 1) * kB; j++) {
                if(cnt_b[i] + cnt[j] == s) {
                    return 1 + preorder[j];
                }
            }
        }
    }
    return -1;
}

int main() 
{
    fin >> n >> m;
    adj = vector<vector<int>>(n);
    for(int i = 1; i < n; i++) {
        int u, v;
        fin >> u >> v;
        u--; v--;
        adj[u].emplace_back(v);
        adj[v].emplace_back(u);
    }

    tin = vector<int>(n);
    tout = vector<int>(n);

    dfs();
    cnt = vector<int>(n);
    for(int i = 0; i * kB <= n; i++) {
        ds[i][0] = 1;
    }
    
    for(int i = 0; i < m; i++) {
        int t, s;
        fin >> t;
        if(t == 1) {
            int u;
            fin >> u >> s;
            u--;
            update(u, s);
        } else {
            fin >> s;
            fout << query(s) << '\n';
        }
    }
    return 0;
}