willy108

V

Dec 22nd, 2021
1,187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.94 KB | None | 0 0
  1.  
  2. //misaka and rin will carry me to cm
  3. #include <iostream>
  4. #include <cstdio>
  5. #include <cstring>
  6. #include <utility>
  7. #include <cassert>
  8. #include <algorithm>
  9. #include <vector>
  10. #include <array>
  11. #include <tuple>
  12.  
  13. #define ll long long
  14. #define lb long double
  15. #define sz(vec) ((int)(vec.size()))
  16. #define all(x) x.begin(), x.end()
  17. #define LC(x) ((x)*2 +1)
  18. #define RC(x) ((x)*2 +2)
  19.  
  20. const lb eps = 1e-9;
  21. const ll mod = 1e9 + 7, ll_max = 1e18;
  22. //const ll mod = (1 << (23)) * 119 +1;
  23. const int MX = 4e5 +10, int_max = 0x3f3f3f3f;
  24.  
  25. using namespace std;
  26.  
  27. //i will learn from moo.
  28. /* Input */
  29. template<class T> void read(T &x) { cin >> x; }
  30. template<class H, class T> void read(pair<H, T> &p) { cin >> p.first >> p.second; }
  31. template<class T, size_t S> void read(array<T, S> &a) { for (T &i : a) read(i); }
  32. template<class T> void read(vector<T> &v) { for (T &i : v) read(i); }
  33.  
  34. template<class H, class... T> void read(H &h, T &...t) { read(h); read(t...); }
  35.  
  36. /* Output */
  37. template<class H, class T> ostream &operator<<(ostream &o, pair<H, T> &p) { o << p.first << " " << p.second; return o; }
  38. template<class T, size_t S> ostream &operator<<(ostream &o, array<T, S> &a) { string s; for (T i : a) o << s << i, s = " "; return o; }
  39. template<class T> ostream &operator<<(ostream &o, vector<T> &v) { string s; for (T i : v) o << s << i, s = " "; return o; }
  40.  
  41. template<class T> void write(T x) { cout << x; }
  42. template<class H, class... T> void write(const H &h, const T &...t) { write(h); write(t...); }
  43.  
  44. void print() { write('\n'); }
  45. template<class H, class... T> void print(const H &h, const T &...t) { write(h); if (sizeof...(t)) write(' '); print(t...); }
  46.  
  47. /* Misc */
  48. template <typename T> void ckmin(T &a, const T &b) { a = min(a, b); }
  49. template <typename T> void ckmax(T &a, const T &b) { a = max(a, b); }
  50.  
  51. int n, q, s = 1;
  52. vector<int> adj[MX];
  53. int sz[MX], in[MX], out[MX], head[MX], dep[MX], par[MX], ind = 0;
  54.  
  55. struct node{
  56.     int pu, pd;
  57.     int su, sd;
  58.     int pud, pdu;
  59.     int sud, sdu;
  60.     int rl, rr;
  61.     int ans;
  62.     int zz;
  63.     node(int a){
  64.         rl = rr = a;
  65.         pu = pd = su = sd = pud = pdu = sud = sdu = ans = zz = 1;
  66.     }
  67.     node(){
  68.         pu = pd = su = sd = pud = pdu = sud = sdu = rl = rr = ans = zz = 0;
  69.     }
  70.     void pr(){
  71.         print("p terms", pu, pd, pud, pdu, "\ns terms", su, sd, sud, sdu, "\nother", rl, rr, ans, zz);
  72.     }
  73.  
  74.     void sw(){
  75.         swap(su, pu);
  76.         swap(sd, pd);
  77.         swap(sdu, pdu);
  78.         swap(sud, pud);
  79.         swap(rr, rl);
  80.     }  
  81.  
  82. } seg[MX];
  83.  
  84. node merge(node a, node b){
  85.     //FerMats Little theorem
  86.     if(a.zz == 0) return b;
  87.     if(b.zz == 0) return a;
  88.     //a + b
  89.     node c = node();
  90.     c.zz = a.zz + b.zz;
  91.     c.rl = a.rl;
  92.     c.rr = b.rr;
  93.  
  94.     c.pu = (a.pu == a.zz && a.rr <= b.rl) ? a.pu + b.pu : a.pu;
  95.     c.pd = (a.pd == a.zz && a.rr >= b.rl) ? a.pd + b.pd : a.pd;
  96.     c.su = (b.su == b.zz && a.rr >= b.rl) ? b.su + a.su : b.su;
  97.     c.sd = (b.sd == b.zz && a.rr <= b.rl) ? b.sd + a.sd : b.sd;
  98.  
  99.     c.pud = (a.pud + b.pd * (a.pud == a.zz && a.rr >= b.rl));
  100.     c.pdu = (a.pdu + b.pu * (a.pdu == a.zz && a.rr <= b.rl));
  101.     c.sud = (b.sud + a.sd * (b.sud == b.zz && a.rr <= b.rl));
  102.     c.sdu = (b.sdu + a.su * (b.sdu == b.zz && a.rr >= b.rl));
  103.     if(a.pu == a.zz) c.pud = max(c.pud, a.pu + b.pud * (a.rr <= b.rl));
  104.     if(a.pd == a.zz) c.pdu = max(c.pdu, a.pd + b.pdu * (a.rr >= b.rl));
  105.     if(b.su == b.zz) c.sud = max(c.sud, b.su + a.sud * (a.rr >= b.rl));
  106.     if(b.sd == b.zz) c.sdu = max(c.sdu, b.sd + a.sdu * (a.rr <= b.rl));
  107.     assert(c.pdu >= c.pd);
  108.     //oh boy
  109.     c.ans = max(a.ans, b.ans);
  110.     if(a.rr <= b.rl){ //1 < 2
  111.         c.ans = max({c.ans, a.sdu + b.pu, a.sd + b.pud});
  112.     }else{
  113.         c.ans = max({c.ans, a.sud + b.pd, a.su + b.pdu});
  114.     }
  115.     c.ans = max({c.ans, c.sud, c.sdu, c.pdu, c.pud});
  116.     return c;
  117. }
  118.  
  119. void U(int p, int v, int k, int L, int R){
  120.     if(p < L || R <= p) return ;
  121.     if(L + 1 == R){
  122.         seg[k] = node(v);
  123.         return ;
  124.     }
  125.     int mid = (L + R)/2;
  126.     U(p, v, LC(k), L, mid);
  127.     U(p, v, RC(k), mid, R);
  128.     seg[k] = merge(seg[LC(k)], seg[RC(k)]);
  129. }
  130.  
  131. node S(int qL, int qR, int k, int L, int R){
  132.     if(qR <= L || R <= qL || R <= L) return node();
  133.     if(qL <= L && R <= qR){
  134.         //print("merged", k);
  135.         return seg[k];
  136.     }
  137.     int mid = (L + R)/2;
  138.     return merge(S(qL, qR, LC(k), L, mid), S(qL, qR, RC(k), mid, R));
  139. }
  140.  
  141. void dfs(int x, int p){
  142.     sz[x] = 1;
  143.     dep[x] = dep[p] + 1;
  144.     par[x] = p;
  145.     for(auto &i : adj[x]){
  146.         if(i == p) continue;
  147.         dfs(i, x);
  148.         sz[x] += sz[i];
  149.         if(adj[x][0] == p || sz[i] > sz[adj[x][0]]) swap(adj[x][0], i);
  150.     }
  151. }
  152.  
  153. void dfs2(int x, int p){
  154.     in[x] = ind++;
  155.     for(auto &i : adj[x]){
  156.         if(i == p) continue;
  157.         head[i] = (i == adj[x][0] ? head[x] : i);
  158.         dfs2(i, x);
  159.     }
  160.     out[x] = ind;
  161. }
  162.  
  163. int lca(int a, int b){
  164.     while(head[a] != head[b]){
  165.         if(dep[head[a]] > dep[head[b]]) swap(a, b);
  166.         b = par[head[b]];
  167.     }
  168.     if(dep[a] > dep[b]) swap(a, b);
  169.     return a;
  170. }
  171.  
  172. node go(int a, int b){
  173.     node left = node();
  174.     node right = node();
  175.     int l = lca(a, b);
  176.     //print(a, b, head[a], head[b]);
  177.     while(head[b] != head[l]){
  178.         node c = S(in[head[b]], in[b]+1, 0, 0, s);
  179.         //c.sw();
  180.         right = merge(c, right);
  181.         b = par[head[b]];
  182.     }
  183.     while(head[a] != head[l]){
  184.         node c = S(in[head[a]], in[a]+1, 0, 0, s);
  185.         c.sw();
  186.         left = merge(left, c);
  187.         a = par[head[a]];
  188.     }
  189.     node temp = node();
  190.     if(dep[a] < dep[b]){
  191.         temp = S(in[a], in[b] + 1, 0, 0, s);
  192.         //temp.sw();
  193.     }else{
  194.         temp = S(in[b], in[a] + 1, 0, 0, s);
  195.         temp.sw();
  196.     }
  197.     return merge(left, merge(temp, right));
  198. }
  199.  
  200. void solve(){
  201.     read(n);
  202.     while(s <= n) s*=2;
  203.     for(int i = 2; i<=n; i++){
  204.         int a, b = i; read(a);
  205.         adj[a].push_back(b);
  206.         b[adj].push_back(a);
  207.     }
  208.     dfs(1, 0);
  209.     head[1] = 1;
  210.     dfs2(1, 0);
  211.     for(int i = 1; i<=n; i++){
  212.         U(in[i], i, 0, 0, s);
  213.     }
  214.     read(q);
  215.     ll ans = 0;
  216.     while(q--){
  217.         ll a, b; read(a, b);
  218.         a ^= ans, b ^= ans;
  219.         //print("a", a, b);
  220.         ans = go(a, b).ans;
  221.         print(ans);
  222.     }
  223. }
  224.  
  225. int main(){
  226.   cin.tie(0) -> sync_with_stdio(0);
  227.     int T = 1;
  228.     //cin >> T;
  229.   while(T--){
  230.         solve();
  231.     }
  232.     return 0;
  233. }
  234.  
  235.  
  236.  
Advertisement
Add Comment
Please, Sign In to add comment