Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <iostream>
- #include <numeric>
- #include <vector>
- typedef long long llong;
- const int MAXN = 200000 + 10;
- const int INF = 1e9;
- int n, q;
- int d[MAXN];
- int sz[MAXN];
- bool has[MAXN];
- int active[MAXN];
- std::vector <int> g[MAXN];
- std::vector <std::pair <int,int>> queries[MAXN];
- std::vector <std::pair <int,int>> adequate[MAXN];
- void initliazeDFS(int node) // първо дете - max sz
- {
- sz[node] = 1;
- for (const int &i : g[node])
- {
- d[i] = d[node] + 1;
- initliazeDFS(i);
- sz[node] += sz[i];
- }
- for (int i = 1 ; i < g[node].size() ; ++i)
- {
- if (sz[g[node][i]] > sz[g[node][0]])
- {
- std::swap(g[node][i], g[node][0]);
- }
- }
- }
- void removeDFS(int node)
- {
- for (const auto &[k, idx] : adequate[node]) // вече adequate ще е изчислено
- {
- has[d[node] + k] = false;
- }
- for (const int &i : g[node])
- {
- removeDFS(i);
- }
- }
- void addDFS(int node)
- {
- for (const auto &[k, idx] : adequate[node]) // вече adequate ще е изчислено
- {
- has[d[node] + k] = true;
- }
- for (const int &i : g[node])
- {
- addDFS(i);
- }
- }
- int cntAdequate;
- void clearQueries(int node)
- {
- if (g[node].empty()) // проверка дали е листо
- {
- return;
- }
- for (int i = 1 ; i < g[node].size() ; ++i)
- {
- clearQueries(g[node][i]);
- removeDFS(g[node][i]);
- }
- // щом не е листо, има нулево дете
- clearQueries(g[node][0]);
- for (int i = 1 ; i < g[node].size() ; ++i)
- {
- addDFS(g[node][i]);
- }
- for (const auto &[k, idx] : queries[node])
- {
- if (!has[k + d[node]])
- {
- adequate[node].emplace_back(k, idx);
- has[k + d[node]] = true;
- }
- }
- cntAdequate += adequate[node].size();
- }
- int atDepth[MAXN];
- int toQuery[MAXN];
- void assignDFS(int node)
- {
- toQuery[node] = atDepth[d[node]];
- for (const auto &[k, idx] : adequate[node])
- {
- atDepth[d[node] + k] = idx;
- }
- for (const int &i : g[node])
- {
- assignDFS(i);
- }
- for (const auto &[k, idx] : adequate[node])
- {
- atDepth[d[node] + k] = 0;
- }
- }
- int currCnt;
- void addNode(int node)
- {
- if (toQuery[node] == 0)
- {
- return;
- }
- currCnt += (active[toQuery[node]] == 0);
- active[toQuery[node]]++;
- }
- void removeNode(int node)
- {
- if (toQuery[node] == 0)
- {
- return;
- }
- active[toQuery[node]]--;
- currCnt -= (active[toQuery[node]] == 0);
- }
- void solve()
- {
- d[1] = 1;
- initliazeDFS(1);
- clearQueries(1);
- assignDFS(1);
- int lPtr = 1;
- int ansL = 0, ansR = INF;
- for (int rPtr = 1 ; rPtr <= n ; ++rPtr)
- {
- addNode(rPtr);
- bool shouldDec = false;
- while (currCnt == cntAdequate) // ако lPtr = rPtr + 1, ще прекъсне
- {
- shouldDec = true;
- removeNode(lPtr++);
- }
- // lPtr ще е първия момент, в който не може
- if (shouldDec) addNode(--lPtr);
- if (currCnt == cntAdequate && ansR - ansL + 1 > rPtr - lPtr + 1)
- {
- ansL = lPtr;
- ansR = rPtr;
- }
- }
- std::cout << ansL << ' ' << ansR << '\n';
- }
- void input()
- {
- int p;
- std::cin >> n;
- for (int i = 2 ; i <= n ; ++i)
- {
- std::cin >> p;
- g[p].push_back(i);
- }
- std::cin >> q;
- for (int i = 1 ; i <= q ; ++i)
- {
- int u, k;
- std::cin >> u >> k;
- queries[u].emplace_back(k, i);
- }
- }
- void fastIOI()
- {
- std::ios_base :: sync_with_stdio(0);
- std::cout.tie(nullptr);
- std::cin.tie(nullptr);
- }
- int main()
- {
- fastIOI();
- input();
- solve();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement