Submission #1183838

#TimeUsernameProblemLanguageResultExecution timeMemory
1183838aminjon__Treasure Hunt (CEOI11_tre)C++17
0 / 100
0 ms320 KiB
#include <bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define endl '\n'
typedef long double ld;
typedef unsigned long long ull;
using namespace std;
const int32_t maxn = 400000;
vector<vector<int32_t>> T;
vector<int32_t> B;
int32_t d[maxn + 1];
int32_t x = 1;
void Tbuild(int32_t n)
{
    B.resize(n + 1);
    B[0] = -1;
    for (int32_t i = 1; i <= n; i++)
    {
        B[i] = B[i >> 1] + 1;
    }
    T.assign(1 + B[n], vector<int32_t>(n + 1));
}

void init()
{
    Tbuild(maxn + 1);
}

void path(int32_t a, int32_t s)
{

    int32_t ls = a;
    for (int32_t i = 1; i <= s; i++)
    {
        x++;
        d[x] = d[ls] + 1;
        T[0][x] = ls;
        for (int32_t j = 1; j <= B[x]; j++)
        {
            T[j][x] = T[j - 1][T[j - 1][x]];
        }
        ls = x;
    }
}
int32_t lift(int32_t a, int32_t up)
{
    for (int32_t i = B[maxn]; i >= 0; i--)
    {
        if ((1 << i) & up)
        {
            a = T[i][a];
        }
    }
    return a;
}
int32_t lca(int32_t a, int32_t b)
{
    if (d[a] > d[b])
    {
        swap(a, b);
    }

    b = lift(b, d[b] - d[a]);

    if (b == a)
    {
        return a;
    }
    for (int32_t i = B[maxn]; i >= 0; i--)
    {
        int32_t pA = T[i][a];
        int32_t pB = T[i][b];
        if (pA != pB)
        {
            a = pA;
            b = pB;
        }
    }
    return T[0][a];
}

int32_t dig(int32_t a, int32_t b)
{

    int32_t P = lca(a, b);
    int32_t L = d[a] - d[P] + d[b] - d[P] + 1;
    int32_t lt = d[a] - d[P] + 1;
    int32_t el = (L+1)/2;
    if (el <= lt)
    {
        return lift(a, el - 1);
    }
    else
    {
        return lift(b, L - el);
    }
}
int main()
{
  int32_t num_calls;
  cin >> num_calls;
  for (int32_t i = 1; i <= num_calls; i++)
  {
    char call[2];
    int32_t a, b;
    cin >> call[0] >> a >> b;
    // scanf("%s%d%d", call, &a, &b);
    if (call[0] == 'i')
      init();
    else if (call[0] == 'p')
      path(a, b);
    else
        cout<<dig(a,b)<<endl;
  }
  return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...