Pagini recente » Cod sursa (job #1902872) | Cod sursa (job #837614) | Cod sursa (job #1317059) | Cod sursa (job #1887933) | Cod sursa (job #3317688)
#include <fstream>
#include <vector>
#include <cmath>
#include <unordered_map>
template <typename T>
using Vec = std::vector<T>;
class SqrtDecomposition {
int N, b_size, b_cnt;
Vec<int> b_lvl, b_vals;
Vec<std::unordered_map<int, int>> b_freq;
public:
SqrtDecomposition(int N)
: N(N), b_size(sqrt(N)), b_cnt((N + b_size - 1) / b_size),
b_vals(N), b_lvl(b_cnt), b_freq(b_cnt) {
for (int i = 0; i < b_cnt; ++i)
b_freq[i][0] = std::min(b_size * (i + 1), N) - i * b_size;
}
void update(int l, int r, int val) {
for (int i = 0; i < b_cnt; ++i) {
int low = i * b_size, high = std::min(N - 1, low + b_size - 1);
if (l <= low && high <= r) b_lvl[i] += val;
else {
int a = std::max(l, low), b = std::min(r, high);
if (a > high || b < low) continue;
for (int j = a; j <= b; ++j) {
--b_freq[i][b_vals[j]];
b_vals[j] += val;
++b_freq[i][b_vals[j]];
}
}
}
}
int query(int sum) {
for (int i = 0; i < b_cnt; ++i)
if (b_freq[i][sum - b_lvl[i]] != 0) {
for (int j = 0; j < b_size; ++j)
if (b_vals[i * b_size + j] == sum - b_lvl[i])
return i * b_size + j;
}
return -2;
}
};
std::pair<Vec<int>, Vec<int>> dfs_flattening(const Vec<Vec<int>> &adj) {
Vec<int> tin(adj.size()), tout(adj.size());
int time = -1;
auto dfs = [&](auto &self, int u, int p = -1) -> void {
tin[u] = ++time;
for (int v : adj[u])
if (v != p) self(self, v, u);
tout[u] = time;
};
dfs(dfs, 0, 0);
return { tin, tout };
}
int main() {
std::ifstream fin("arbore.in");
std::ofstream fout("arbore.out");
int N, M;
fin >> N >> M;
Vec<Vec<int>> adj(N);
for (int i = 0; i < N - 1; ++i) {
int u, v;
fin >> u >> v;
adj[u - 1].push_back(v - 1);
adj[v - 1].push_back(u - 1);
}
auto[tin, tout] = dfs_flattening(adj);
SqrtDecomposition decomp(N);
for (int i = 0; i < M; ++i) {
int type;
fin >> type;
if (type == 1) {
int u, val;
fin >> u >> val;
decomp.update(tin[u - 1], tout[u - 1], val);
} else {
int sum;
fin >> sum;
fout << decomp.query(sum) + 1 << '\n';
}
}
fin.close();
fout.close();
return 0;
}