Advertisement
volochai

LCA 287 E

Mar 8th, 2023
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.46 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #define ll long long
  4. #define all(x) (x).begin(), (x).end()
  5. #define rall(x) (x).rbegin(), (x).rend()
  6. #define watch(x) cout << (#x) <<  " : " << x << '\n'
  7. #define boost ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
  8.  
  9. using namespace std;
  10.  
  11. struct item {
  12.     int min_val;
  13.     int max_val;
  14.     int min_id;
  15.     int max_id;
  16.  
  17.     void init(int v, int pos) {
  18.         min_val = max_val = v;
  19.         min_id = max_id = pos;
  20.     }
  21. };
  22.  
  23. item merge(item a, item b) {
  24.     item res;
  25.     if (a.max_val > b.max_val)
  26.         res.max_val = a.max_val, res.max_id = a.max_id;
  27.     else
  28.         res.max_val = b.max_val, res.max_id = b.max_id;
  29.     if (a.min_val < b.min_val)
  30.         res.min_val = a.min_val, res.min_id = a.min_id;
  31.     else
  32.         res.min_val = b.min_val, res.min_id = b.min_id;
  33.     return res;
  34. }
  35.  
  36. struct segtree {
  37.     vector < item > t;
  38.     int base, N;
  39.  
  40.     void init(vector<int>& a) {
  41.         int n = (int)a.size();
  42.         t.resize(4 * n);
  43.         build(a, 1, 0, n - 1);
  44.         N = n;
  45.     }
  46.  
  47.     void build(vector<int>& a, int v, int tl, int tr) {
  48.         if (tl == tr) {
  49.             t[v].init(a[tl], tl);
  50.             return;
  51.         }
  52.         int tm = (tl + tr) >> 1;
  53.         build(a, v << 1, tl, tm);
  54.         build(a, v << 1 | 1, tm + 1, tr);
  55.         t[v] = merge(t[v << 1], t[v << 1 | 1]);
  56.     }
  57.  
  58.     item get(int l, int r, int v, int tl, int tr) {
  59.         if (tl > r || tr < l)
  60.             return item{(int)2e9, (int)-2e9, -1, -1};
  61.         if (l <= tl && tr <= r)
  62.             return t[v];
  63.         int tm = (tl + tr) >> 1;
  64.         return merge(get(l, r, v << 1, tl, tm),
  65.                      get(l, r, v << 1 | 1, tm + 1, tr));
  66.     }
  67.  
  68.     item get(int l, int r) {
  69.         if (l > r)
  70.             return item{(int)2e9, (int)-2e9, -1, -1};
  71.         return get(l, r, 1, 0, N - 1);
  72.     }
  73. };
  74.  
  75. const int N = 1e5 + 128;
  76. const int LOG = 20;
  77. int lift[N][LOG];
  78. int depth[N];
  79. int tin[N], tout[N];
  80. vector <int> g[N];
  81. int n, q;
  82. int timer;
  83. vector <int> order;
  84.  
  85. void dfs(int v, int d = 0, int p = 1) {
  86.     order.push_back(v);
  87.     tin[v] = timer++;
  88.     depth[v] = d;
  89.  
  90.     lift[v][0] = p;
  91.     for (int b = 1; b < LOG; b++)
  92.         lift[v][b] = lift[lift[v][b-1]][b-1];
  93.  
  94.     for (auto to : g[v])
  95.         if (to != p)
  96.             dfs(to, d + 1, v);
  97.  
  98.     order.push_back(v);
  99.     tout[v] = timer++;
  100. }
  101.  
  102. void solve() {
  103.     cin >> n >> q;
  104.     for (int i = 2; i <= n; i++) {
  105.         int x;
  106.         cin >> x;
  107.         g[i].push_back(x);
  108.         g[x].push_back(i);
  109.     }
  110.  
  111.     dfs(1);
  112.  
  113.     segtree tmin, tmax, thei;
  114.  
  115.     vector <int> ttin, ttout;
  116.     for (int i = 0; i < n; i++)
  117.         ttin.push_back(tin[i + 1]), ttout.push_back(tout[i + 1]);
  118.  
  119.     tmin.init(ttin);
  120.     tmax.init(ttout);
  121.  
  122.     vector<int> heii;
  123.     for (auto c : order)
  124.         heii.push_back(depth[c]);
  125.  
  126.     thei.init(heii);
  127.  
  128.     while (q--) {
  129.         int l, r;
  130.         cin >> l >> r;
  131.  
  132.         l--; r--;
  133.  
  134.         auto t_min = tmin.get(l, r);
  135.         auto t_max = tmax.get(l, r);
  136.  
  137.         int delete_left = t_min.min_id;
  138.         int delete_right = t_max.max_id;
  139.  
  140.         int delete_ans = -1;
  141.         int ans = -1;
  142.  
  143.         auto t_min_without_deleted_left = merge(tmin.get(l, delete_left - 1), tmin.get(delete_left + 1, r));
  144.         auto t_max_without_deleted_right = merge(tmax.get(l, delete_right - 1), tmax.get(delete_right + 1, r));
  145.  
  146.         int without_left_ans, without_right_ans;
  147.  
  148.         if (t_min_without_deleted_left.min_val + 1 >= t_min_without_deleted_left.max_val)
  149.             without_left_ans = thei.get(t_min_without_deleted_left.min_val, t_min_without_deleted_left.max_val).min_val + 1;
  150.         else
  151.             without_left_ans = thei.get(t_min_without_deleted_left.min_val + 1, t_min_without_deleted_left.max_val - 1).min_val;
  152.  
  153.         if (t_max_without_deleted_right.min_val + 1 >= t_max_without_deleted_right.max_val)
  154.             without_right_ans = thei.get(t_max_without_deleted_right.min_val, t_max_without_deleted_right.max_val).min_val + 1;
  155.         else
  156.             without_right_ans = thei.get(t_max_without_deleted_right.min_val + 1, t_max_without_deleted_right.max_val - 1).min_val;
  157.  
  158.         if (ans < without_left_ans)
  159.             ans = without_left_ans, delete_ans = delete_left;
  160.         if (ans < without_right_ans)
  161.             ans = without_right_ans, delete_ans = delete_right;
  162.  
  163.         cout << delete_ans + 1 << ' ' << ans - 1 << '\n';
  164.     }
  165. }
  166.  
  167. main() {
  168.     boost;
  169.     solve();
  170.     return 0;
  171. }
  172.  
  173.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement