ProgMe

Codeforces_forever Round #1 (Div3) B2

Apr 25th, 2020
198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.60 KB | None | 0 0
  1. //решение
  2. В этой задаче мы можем заметить, что когда мы считаем ответ для ребенка i, мы также считаем ответ для детей pi, ppi и так далее. Таким образом, мы можем немного модифицировать псевдокод из простой версии, чтобы считать ответы быстрее:
  3.  
  4.  
  5. pos = p[i]
  6. ans = 1
  7. cycle = [i]
  8. while pos != i:
  9. cycle.append(pos)
  10. ans += 1
  11. pos = p[pos]
  12. for el in cycle: res[el] = ans
  13. И, конечно же, нет необходимости запускать этот while для всех элементов, для которых мы уже посчитали ответ. Асимптотика решения — O(n), потому что вы обработаете каждый элемент единожды.
  14. //реализация
  15. #include <bits/stdc++.h>
  16.  
  17. using namespace std;
  18.  
  19. int main() {
  20. #ifdef _DEBUG
  21. freopen("input.txt", "r", stdin);
  22. // freopen("output.txt", "w", stdout);
  23. #endif
  24.  
  25. int q;
  26. cin >> q;
  27. for (int i = 0; i < q; ++i) {
  28. int n;
  29. cin >> n;
  30. vector<int> p(n);
  31. for (int j = 0; j < n; ++j) {
  32. cin >> p[j];
  33. --p[j];
  34. }
  35. vector<int> used(n);
  36. vector<int> ans(n);
  37. for (int j = 0; j < n; ++j) {
  38. if (!used[j]) {
  39. vector<int> cur;
  40. while (!used[j]) {
  41. cur.push_back(j);
  42. used[j] = true;
  43. j = p[j];
  44. }
  45. for (auto el : cur) ans[el] = cur.size();
  46. }
  47. }
  48. for (int j = 0; j < n; ++j) cout << ans[j] << " ";
  49. cout << endl;
  50. }
  51.  
  52. return 0;
  53. }
Advertisement
Add Comment
Please, Sign In to add comment