Cod sursa(job #2038865)

Utilizator TincaMateiTinca Matei TincaMatei Data 14 octombrie 2017 02:30:16
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <bits/stdc++.h>

const int MAX_N = 100000;
const int BUCK = 317;
const int MAX_S = 1000000;

std::vector<int> graph[1+MAX_N];
int top;
int first[1+MAX_N], last[1+MAX_N];
int val[1+MAX_N];
int liniar[1+MAX_N];

void dfs(int nod, int papa) {
  liniar[top] = nod;
  first[nod] = top++;
  for(auto it: graph[nod])
    if(it != papa)
      dfs(it, nod);
  last[nod] = top - 1;
}

std::bitset<1+MAX_S> fr[BUCK];
int dif[BUCK];

static inline void clearbuck(int b) {
  for(int i = b * BUCK; i < (b + 1) * BUCK && i < top; ++i)
    if(0 <= val[i] && val[i] <= MAX_S)
      fr[b][val[i]] = 0;
}

static inline void updbuck(int b) {
  for(int i = b * BUCK; i < (b + 1) * BUCK && i < top; ++i)
    if(0 <= val[i] && val[i] <= MAX_S)
      fr[b][val[i]] = 1;
}

static inline void updbuckrange(int l, int r, int valupd) {
  int b = l / BUCK;
  clearbuck(b);
  for(int i = l; i <= r; ++i)
    val[liniar[i]] += valupd;
  updbuck(b);
}

static inline void update(int l, int r, int valupd) {
  int buckl = l / BUCK, buckr = r / BUCK;
  if(buckl == buckr)
    updbuckrange(l, r, valupd);
  else {
    if(l % BUCK > 0)
      updbuckrange(l, (buckl + 1) * BUCK - 1, valupd);
    else
      --buckl;
    
    if(r % BUCK < BUCK - 1)
      updbuckrange(buckr * BUCK, r, valupd);
    else
      ++buckr;
    for(int i = buckl + 1; i < buckr; ++i)
      dif[i] += valupd;
  }
}

const int BUFFER = 1 << 17;

int curs = BUFFER - 1;
char buff[BUFFER];

static inline char getch(FILE *fin) {
  ++curs;
  if(curs == BUFFER) {
    curs = 0;
    fread(buff, 1, BUFFER, fin);
  }
  return buff[curs];
}

static inline int getnr(FILE *fin) {
  int nr = 0;
  char ch = getch(fin);
  while(!isdigit(ch))
    ch = getch(fin);
  while(isdigit(ch)) {
    nr = nr * 10 + ch - '0';
    ch = getch(fin);
  }
  return nr;
}

int getrez(int b, int s) {
  int i = b * BUCK;
  while(i < (b + 1) * BUCK && i < top && val[liniar[i]] != s)
    ++i;
  return liniar[i];
}

int main() {
  int n, m, a, b, tip;
  FILE *fin = fopen("arbore.in", "r");
  FILE *fout = fopen("arbore.out", "w");
  n = getnr(fin);
  m = getnr(fin);
  for(int i = 0; i < n - 1; ++i) {
    a = getnr(fin);
    b = getnr(fin);
    graph[a].push_back(b);
    graph[b].push_back(a);
  }
  
  dfs(1, -1);
  
  for(int i = 0; i < m; ++i) {
    tip = getnr(fin);
    if(tip == 1) {
      a = getnr(fin);
      b = getnr(fin);
      update(first[a], last[a], b);
    } else {
      int rez = -1;
      a = getnr(fin);
      b = 0;
      while(b < top / BUCK + 1 && rez == -1) {
        int s = a - dif[b];
        if(0 <= s && fr[b][s])
          rez = b;
      }
      if(rez != -1)
        rez = getrez(rez, a - dif[rez]);
      fprintf(fout, "%d\n", rez);
    }
  }

  fclose(fin);
  fclose(fout);
  return 0;
}