Cod sursa(job #2923909)

Utilizator iancupoppPopp Iancu Alexandru iancupopp Data 20 septembrie 2022 22:00:53
Problema Arbore Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.05 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <cmath>

using namespace std;

const int N = 1e5;
const int M = 1e6;
const int RAD = sqrt(2 * N);

vector<int> fii[N + 1];
vector<int> lin;
int st[N + 1], dr[N + 1];
bitset<M + 1> bs[RAD + 1];
int lazy[RAD + 1];
int s[2 * N + 1];

void dfs(int nod) {
  st[nod] = lin.size();
  lin.push_back(nod);
  for (auto f: fii[nod]) {
    dfs(f);
  }
  dr[nod] = lin.size();
  lin.push_back(nod);
}

int bucket(int x) {
  return x / RAD;
}

void reset(int b) {
  int l = b * RAD, r = min((b + 1) * RAD, (int)lin.size()) - 1;
  for (int i = l; i <= r; ++i) {
    bs[b][s[i]] = 0;
    s[i] += lazy[b];
  }
  lazy[b] = 0;
}

void update(int l, int r, int add) {
  int b1 = bucket(l), b2 = bucket(r);
  if (b1 < b2) {
    for (int b = b1 + 1; b < b2; ++b) {
      lazy[b] += add;
    }
    reset(b1), reset(b2);
    for (int i = l; i < (b1 + 1) * RAD; ++i) {
      s[i] += add;
    }
    for (int i = b1 * RAD; i < (b1 + 1) * RAD; ++i) {
      bs[b1][s[i]] = 1;
    }
    for (int i =  b2 * RAD; i <= r; ++i) {
      s[i] += add;
    }
    for (int i = b2 * RAD; i < (b2 + 1) * RAD; ++i) {
      bs[b2][s[i]] = 1;
    }
  } else {
    reset(b1);
    for (int i = l; i <= r; ++i) {
      s[i] += add;
    }
    for (int i = b1 * RAD; i < (b1 + 1) * RAD; ++i) {
      bs[b1][s[i]] = 1;
    }
  }
}

int query(int sum) {
  for (int b = 0; b <= RAD; ++b) {
    if (bs[b][sum - lazy[b]]) {
      for (int i = b * RAD; i < (b + 1) * RAD; ++i) {
        if (lazy[b] + s[i] == sum) {
          return lin[i];
        }
      }
    }
  }
  return -1;
}

int main() {
  ifstream cin("arbore.in");
  ofstream cout("arbore.out");
  int n, q;
  cin >> n >> q;
  for (int i = 0; i < n - 1; ++i) {
    int tata, fiu;
    cin >> tata >> fiu;
    fii[tata].push_back(fiu);
  }
  dfs(1);
  while (q--) {
    int op;
    cin >> op;
    if (op == 1) {
      int nod, add;
      cin >> nod >> add;
      update(st[nod], dr[nod], add);
    } else {
      int sum;
      cin >> sum;
      cout << query(sum) << "\n";
    }
  }
  cin.close();
  cout.close();
  return 0;
}