Advertisement
libobil

Untitled

May 27th, 2023
654
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.94 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <numeric>
  4. #include <vector>
  5.  
  6. typedef long long llong;
  7. const int MAXN = 200000 + 10;
  8. const int INF  = 1e9;
  9.  
  10. int n, q;
  11. int d[MAXN];
  12. int sz[MAXN];
  13. bool has[MAXN];
  14. int active[MAXN];
  15. std::vector <int> g[MAXN];
  16. std::vector <std::pair <int,int>> queries[MAXN];
  17. std::vector <std::pair <int,int>> adequate[MAXN];
  18.  
  19. void initliazeDFS(int node) // първо дете - max sz
  20. {
  21.     sz[node] = 1;
  22.     for (const int &i : g[node])
  23.     {
  24.         d[i] = d[node] + 1;
  25.         initliazeDFS(i);
  26.         sz[node] += sz[i];
  27.     }
  28.  
  29.     for (int i = 1 ; i < g[node].size() ; ++i)
  30.     {
  31.         if (sz[g[node][i]] > sz[g[node][0]])
  32.         {
  33.             std::swap(g[node][i], g[node][0]);
  34.         }
  35.     }
  36. }
  37.  
  38. void removeDFS(int node)
  39. {
  40.     for (const auto &[k, idx] : adequate[node]) // вече adequate ще е изчислено
  41.     {
  42.         has[d[node] + k] = false;
  43.     }
  44.  
  45.     for (const int &i : g[node])
  46.     {
  47.         removeDFS(i);
  48.     }
  49. }
  50.  
  51. void addDFS(int node)
  52. {
  53.     for (const auto &[k, idx] : adequate[node]) // вече adequate ще е изчислено
  54.     {
  55.         has[d[node] + k] = true;
  56.     }
  57.  
  58.     for (const int &i : g[node])
  59.     {
  60.         addDFS(i);
  61.     }
  62. }
  63.  
  64. int cntAdequate;
  65. void clearQueries(int node)
  66. {
  67.     if (g[node].empty()) // проверка дали е листо
  68.     {
  69.         return;
  70.     }
  71.  
  72.     for (int i = 1 ; i < g[node].size() ; ++i)
  73.     {
  74.         clearQueries(g[node][i]);
  75.         removeDFS(g[node][i]);
  76.     }
  77.  
  78.     // щом не е листо, има нулево дете
  79.     clearQueries(g[node][0]);
  80.     for (int i = 1 ; i < g[node].size() ; ++i)
  81.     {
  82.         addDFS(g[node][i]);
  83.     }
  84.  
  85.     for (const auto &[k, idx] : queries[node])
  86.     {
  87.         if (!has[k + d[node]])
  88.         {
  89.             adequate[node].emplace_back(k, idx);
  90.             has[k + d[node]] = true;
  91.         }
  92.     }
  93.  
  94.     cntAdequate += adequate[node].size();
  95. }
  96.  
  97. int atDepth[MAXN];
  98. int toQuery[MAXN];
  99. void assignDFS(int node)
  100. {
  101.     toQuery[node] = atDepth[d[node]];
  102.     for (const auto &[k, idx] : adequate[node])
  103.     {
  104.         atDepth[d[node] + k] = idx;
  105.     }
  106.  
  107.     for (const int &i : g[node])
  108.     {
  109.         assignDFS(i);
  110.     }
  111.  
  112.     for (const auto &[k, idx] : adequate[node])
  113.     {
  114.         atDepth[d[node] + k] = 0;
  115.     }
  116. }
  117.  
  118. int currCnt;
  119. void addNode(int node)
  120. {
  121.     if (toQuery[node] == 0)
  122.     {
  123.         return;
  124.     }
  125.  
  126.     currCnt += (active[toQuery[node]] == 0);
  127.     active[toQuery[node]]++;
  128. }
  129.  
  130. void removeNode(int node)
  131. {
  132.     if (toQuery[node] == 0)
  133.     {
  134.         return;
  135.     }
  136.  
  137.     active[toQuery[node]]--;
  138.     currCnt -= (active[toQuery[node]] == 0);
  139. }
  140.  
  141. void solve()
  142. {  
  143.     d[1] = 1;
  144.     initliazeDFS(1);
  145.     clearQueries(1);
  146.     assignDFS(1);
  147.  
  148.     int lPtr = 1;
  149.     int ansL = 0, ansR = INF;
  150.     for (int rPtr = 1 ; rPtr <= n ; ++rPtr)
  151.     {
  152.         addNode(rPtr);
  153.         bool shouldDec = false;
  154.         while (currCnt == cntAdequate) // ако lPtr = rPtr + 1, ще прекъсне
  155.         {
  156.             shouldDec = true;
  157.             removeNode(lPtr++);
  158.         }
  159.        
  160.         // lPtr ще е първия момент, в който не може
  161.         if (shouldDec) addNode(--lPtr);
  162.  
  163.         if (currCnt == cntAdequate && ansR - ansL + 1 > rPtr - lPtr + 1)
  164.         {
  165.             ansL = lPtr;
  166.             ansR = rPtr;
  167.         }
  168.     }
  169.  
  170.     std::cout << ansL << ' ' << ansR << '\n';
  171. }
  172.  
  173. void input()
  174. {
  175.     int p;
  176.     std::cin >> n;
  177.     for (int i = 2 ; i <= n ; ++i)
  178.     {
  179.         std::cin >> p;
  180.         g[p].push_back(i);
  181.     }
  182.  
  183.     std::cin >> q;
  184.     for (int i = 1 ; i <= q ; ++i)
  185.     {
  186.         int u, k;
  187.         std::cin >> u >> k;
  188.         queries[u].emplace_back(k, i);
  189.     }
  190. }
  191.  
  192. void fastIOI()
  193. {
  194.     std::ios_base :: sync_with_stdio(0);
  195.     std::cout.tie(nullptr);
  196.     std::cin.tie(nullptr);
  197. }
  198.  
  199. int main()
  200. {
  201.     fastIOI();
  202.     input();
  203.     solve();
  204.  
  205.     return 0;
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement