Cod sursa(job #2039032)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 14 octombrie 2017 10:44:42
Problema Arbore Scor 95
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <cstdio>
#include <vector>
#include <bitset>
#include <algorithm>

using namespace std;

const int MAX_N = 100000;
const int MAX_B = 323;
const int MAX_V = 1000000;

vector<int>G[1 + MAX_N];
int lin[1 + MAX_N];
int val[1 + MAX_N];
int first[1 + MAX_N], last[1 + MAX_N];
int lazy[1 + MAX_B];
bitset<1 + MAX_V>b[1 + MAX_B];
bool viz[1 + MAX_N];

int N, M;
int k;
int bucketSize;

void getLin(int node) {
  lin[++k] = node;
  first[node] = k;
  viz[node] = true;
  for (auto it:G[node]) {
    if (!viz[it]) {
      getLin(it);
    }
  }
  last[node] = k;
}

void recompute(int bucket) {
  int st = (bucket - 1) * bucketSize + 1;
  int dr = min(N, bucket * bucketSize);
  for (int i = st; i <= dr; ++i)
    b[bucket][i] = 0;
  for (int i = st; i <= dr; ++i) {
    val[i] += lazy[bucket];
    b[bucket][val[i]] = 1;
  }
  lazy[bucket] = 0;
}

void update(int st, int dr, int x) {
  int b1 = (st / bucketSize) + (st % bucketSize != 0);
  int b2 = (dr / bucketSize) + (dr % bucketSize != 0);
  if (b1 != b2) {
    int b1E = min(N, b1 * bucketSize);
    int b2B = (b2 - 1) * bucketSize + 1;
    for (int i = st; i <= b1E; ++i) {
      b[b1][val[i]] = 0;
      val[i] += x;
    }
    for (int i = b2B; i <= dr; ++i) {
      b[b2][val[i]] = 0;
      val[i] += x;
    }
    recompute(b1);
    recompute(b2);
    for (int i = b1 + 1; i <= b2 - 1; ++i)
      lazy[i] += x;
  } else {
    int bB = (b1 - 1) * bucketSize + 1;
    int bE = b1 * bucketSize;
    for (int i = bB; i <= bE; ++i)
      b[b1][val[i]] = 0;
    for (int i = st; i <= dr; ++i)
      val[i] += x;
    recompute(b1);
  }
}

int query(int x) {
  for (int i = 1; i <= MAX_B; ++i) {
    if (x >= lazy[i] && b[i][x - lazy[i]]) {
      int bE = (i - 1) * bucketSize + 1;
      int bB = i * bucketSize;
      for (int j = bE; j <= bB; ++j)
        if (val[j] == x - lazy[i])
          return lin[j];
    }
  }
  return -1;
}

int main() {
  freopen("arbore.in", "r", stdin);
  freopen("arbore.out", "w", stdout);

  scanf("%d%d", &N, &M);
  for (int i = 1; i < N; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    G[u].push_back(v);
    G[v].push_back(u);
  }

  getLin(1);
  bucketSize = N / MAX_B + (N % MAX_B != 0);

  for (int i = 1; i <= MAX_B; ++i)
    b[i][0] = 1;

  for (int i = 1; i <= M; ++i) {
    int t;
    scanf("%d", &t);
    if (t == 1) {
      int p, s;
      scanf("%d%d", &p, &s);
      update(first[p], last[p], s);
    } else {
      int s;
      scanf("%d", &s);
      printf("%d\n", query(s));
    }
  }

  return 0;
}