Cod sursa(job #3233501)

Utilizator iusty64Iustin Epanu iusty64 Data 3 iunie 2024 17:35:33
Problema Arbore Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.41 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fin ("arbore.in");
ofstream fout ("arbore.out");

const int nmax = 1e5 + 1, sqmax = 318;

unordered_map <int,int> fr[sqmax];
vector<int> L[nmax];

int m, n, sq, siz, i; 
int subarb[nmax]; 
int poz[nmax], sum[nmax], v[nmax]; 
int st[sqmax], dr[sqmax], sumbuc[sqmax]; 


void dfs (int node, int father){
  subarb[node] = 1;
  v[i] = node;
  poz[node] = i++;
  for(auto son : L[node]){
    if(son != father)
      dfs(son, node);
  }
  subarb[father] += subarb[node];
}

void update (int root, int val){
  int x = poz[root], y = x + subarb[root] - 1; 
  int stbuc = (x / sq), drbuc = (y / sq);
  if(drbuc == stbuc){
    for(int i = x; i <= y; ++i){
      fr[drbuc][sum[i]]--; 
      if(fr[drbuc][sum[i]] == 0)
        fr[drbuc].erase (fr[drbuc].find (sum[i]));
      sum[i] += val;
      fr[drbuc][sum[i]]++; 
    }
  }
  else {
    for(int i = x; i <= dr[stbuc]; ++i){ 
      fr[stbuc][sum[i]]--;
      if(fr[stbuc][sum[i]]==0)
        fr[stbuc].erase(fr[stbuc].find (sum[i]));
      sum[i] += val;
      fr[stbuc][sum[i]]++;
    }
    for(int i = y; i >= st[drbuc]; --i){ 
      fr[drbuc][sum[i]]--;
      if(fr[drbuc][sum[i]]==0)
        fr[drbuc].erase(fr[drbuc].find (sum[i]));
      sum[i] += val;
      fr[drbuc][sum[i]]++;
    }
    for(int i = stbuc + 1; i < drbuc; ++i){ 
      sumbuc[i] += val;
    }
  }
}
int query (int s){
  for(int i = 0; i < siz; ++i){ 
    if(fr[i].find(s - sumbuc[i]) != fr[i].end()){ 
      for(int sol = st[i]; sol <= dr[i]; ++sol){ 
        if(sum[sol] == s - sumbuc[i]){ 
          return v[sol];
        }
      }
    }
  }
  return -1;
}

int main()
{
    fin >> n >> m;
    sq = sqrt(n); 
    siz = n / sq + 1;
    if (n % sq == 0) siz--;
    st[0] = 0;
    dr[0] = sq - 1;
    for(int i = 1; i < siz; ++i){
      st[i] = st[i - 1] + sq;
      dr[i] = dr[i - 1] + sq;
    }
    dr[siz - 1] = n - 1;
    for(int i = 0; i < siz; ++i)
      fr[i][0] = dr[i] - st[i] + 1; 
    for(int i = 1; i < n; ++i){
      int x, y;
      fin >> x >> y;
      L[x].push_back(y);
      L[y].push_back(x);
    }
    dfs(1, 0);
    while (m--){
      int q;
      fin >> q;
      if(q == 1){
        int root, val;
        fin >> root >> val;
        update(root, val);
      }
      else{
        int s;
        fin >> s;
        fout << query(s) << "\n";
      }
    }
    return 0;
}