Cod sursa(job #1747678)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 25 august 2016 12:59:02
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <fstream>
#include <algorithm>
#include <unordered_set>

using namespace std;

const int kMaxN = 100005;
const int kMaxB = sqrt(kMaxN);
const int kStep = sqrt(kMaxN);
const int kMaxVal = 1000005;

int n, m, time;
int order[kMaxN];
int time_in[kMaxN], time_out[kMaxN];
int add[kMaxB], current[kMaxB];
vector<int> graph[kMaxN];
unordered_multiset<int> vals[kMaxB];

inline int BucketBegin(int i) { return (i - 1) * kStep + 1; }
inline int BucketEnd(int i) { return min(n, i * kStep); }
inline int BucketId(int i) { return (i - 1) / kStep + 1; }

void Dfs(int x, int p) {
  ++order[0];
  order[order[0]] = x;
  time_in[x] = order[0]; 
  for(auto y : graph[x]) {
    if(y != p) {
      Dfs(y, x);
    }
  }
  time_out[x] = order[0];
}

void UpdateChunk(int l, int r, int s, int ch_id) {
  for(int i = l; i <= r; i++) {
    auto it = vals[ch_id].find(current[order[i]]);
    if(it != vals[ch_id].end()) vals[ch_id].erase(it);
    current[order[i]] += s;
    vals[ch_id].insert(current[order[i]]);
  }
} 

void Update(int l, int r, int s) {
  int id_l = BucketId(l), id_r = BucketId(r);
  if(id_l == id_r) UpdateChunk(l, r, s, id_l);
  else {
    UpdateChunk(l, BucketEnd(id_l), s, id_l);
    UpdateChunk(BucketBegin(id_r), r, s, id_r);
    for(int i = id_l + 1; i <= id_r - 1; i++) add[i] += s;
  }
}

int Query(int s) {
  int ret = -1;
  for(int i = 1; i <= BucketId(n) && ret == -1; i++) {
    if(vals[i].find(s - add[i]) != vals[i].end()) {
      for(int j = BucketBegin(i); j <= BucketEnd(i) && ret == -1; j++) {
        if(current[order[j]] + add[i] == s) {
          ret = order[j];
        }
      }
    }
  }
  return ret;
}

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 x, y;
    scanf("%d %d", &x, &y);
    graph[x].push_back(y);
    graph[y].push_back(x);
  }
  
  for(int i = 1; i <= n; i++) 
    vals[BucketId(i)].insert(0);
  
  Dfs(1, 0);
  while(m--) {
    int op, x, s;
    scanf("%d", &op);
    if(op == 1) {
      scanf("%d %d", &x, &s);
      Update(time_in[x], time_out[x], s);
    } else {
      scanf("%d", &s);
      printf("%d\n", Query(s));
    }
  }
  return 0;
}