Cod sursa(job #2398928)

Utilizator cella.florescuCella Florescu cella.florescu Data 6 aprilie 2019 14:15:39
Problema Arbore Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.09 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1e5;
const int MAXV = 1e6;
const int BUCK = 8;

vector < int > g[MAXN + 1];
int v[MAXN + 1], frst[MAXN + 1], lst[MAXN + 1], wh_node[MAXN + 1], lazy[(MAXN >> BUCK) + 1], sb[(MAXN >> BUCK) + 1], eb[(MAXN >> BUCK) + 2], indx, n, num_b;
bitset < MAXV + 1 > freq[(MAXN >> BUCK) + 1];

void dfs(int node, int father = 0) {
  wh_node[++indx] = node;
  frst[node] = indx;
  for (auto it : g[node])
    if (it ^ father)
      dfs(it, node);
  lst[node] = indx;
}

inline void update(int l, int r, int val) {
  int b = ((l - 1) >> BUCK) + 1;
  for (int i = sb[b]; i <= eb[b]; ++i)
    freq[b][v[i]] = 0;
  for (int i = l; i <= r && i <= eb[b]; ++i)
    v[i] += val;
  for (int i = sb[b]; i <= eb[b]; ++i)
    freq[b][v[i]] = 1;
  if (b == ((r - 1) >> BUCK) + 1)
    return;
  for (b = b + 1; eb[b] <= r; ++b)
    lazy[b] += val;
  for (int i = sb[b]; i <= eb[b]; ++i)
    freq[b][v[i]] = 0;
  for (int i = sb[b]; i <= r; ++i)
    v[i] += val;
  for (int i = sb[b]; i <= eb[b]; ++i)
    freq[b][v[i]] = 1;
}

inline int query(int val) {
  int b;
  for (b = 1; eb[b] <= n; ++b)
    if (val >= lazy[b] && freq[b][val - lazy[b]])
      for (int i = sb[b]; i <= eb[b]; ++i)
        if (v[i] + lazy[b] == val)
          return wh_node[i];
  return -1;
}

int main()
{
    int m;
    ifstream fin("arbore.in");
    fin >> n >> m;
    for (int i = 1; i < n; ++i) {
      int x, y;
      fin >> x >> y;
      g[x].push_back(y);
      g[y].push_back(x);
    }
    dfs(1);
    num_b = 0;
    do {
      freq[++num_b][0] = 1;
      sb[num_b] = ((num_b - 1) << BUCK) + 1;
      eb[num_b] = (num_b << BUCK);
    } while (eb[num_b] < n);
    eb[num_b] = n; sb[num_b + 1] = eb[num_b + 1] = n + 1;
    ofstream fout("arbore.out");
    for (int i = 0; i < m; ++i) {
      int type, x, y;
      fin >> type;
      if (type == 1) {
        fin >> x >> y;
        update(frst[x], lst[x], y);
      } else {
        fin >> x;
        fout << query(x) << '\n';
      }
    }
    fin.close();
    fout.close();
    return 0;
}