Advertisement
PlanttPastes

Олимпијада (мои '16)

Apr 9th, 2025 (edited)
398
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.69 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #pragma GCC optimize("O2,O3,Ofast,unroll-loops")
  4.  
  5. const int N = 107308, inf = 1797710308;
  6. int n, L, H, s;
  7. vector <pair <int, int>> g[N];
  8. int sgt[3 * N], subtsize[N];
  9. bool resetsgt[3 * N], visited[N];
  10.  
  11. void sgtupdate(int q, int val, int node, int cl, int cr) {
  12.     if (q < cl || cr < q) return;
  13.     if (resetsgt[node]) {
  14.         if (node < s) resetsgt[2 * node + 1] = resetsgt[2 * node + 2] = true;
  15.         sgt[node] = -inf;
  16.         resetsgt[node] = false;
  17.     }
  18.     if (q == cl && q == cr) {
  19.         sgt[node] = max(sgt[node], val);
  20.         return;
  21.     }
  22.     int cm = cl + cr >> 1;
  23.     sgtupdate(q, val, 2 * node + 1, cl, cm);
  24.     sgtupdate(q, val, 2 * node + 2, cm + 1, cr);
  25.     sgt[node] = max(resetsgt[2 * node + 1] ? -inf : sgt[2 * node + 1], resetsgt[2 * node + 2] ? -inf : sgt[2 * node + 2]);
  26. }
  27. int sgtget(int ql, int qr, int node, int cl, int cr) {
  28.     if (qr < cl || cr < ql) return -inf;
  29.     if (resetsgt[node]) return -inf;
  30.     if (ql <= cl && cr <= qr) return sgt[node];
  31.     int cm = cl + cr >> 1;
  32.     return max(sgtget(ql, qr, 2 * node + 1, cl, cm), sgtget(ql, qr, 2 * node + 2, cm + 1, cr));
  33. }
  34. int &calcsubt(const int &node, const int &parent) {
  35.     subtsize[node] = 1;
  36.     for (auto &[neigh, _] : g[node]) {
  37.         if (visited[neigh] || neigh == parent) continue;
  38.         subtsize[node] += calcsubt(neigh, node);
  39.     }
  40.     return subtsize[node];
  41. }
  42. bool querydfs(const int &node, const int &parent, const int &depth, const int &val, const int &median) {
  43.     if (sgtget(L - depth, H - depth, 0, 0, s) + val >= 0) {
  44.         // cerr << "FOUND IT!\n";
  45.         return true; // NAJDOVME!! se vrakame do binary searchot
  46.     }
  47.     for (auto &[child, w] : g[node]) {
  48.         if (child == parent || visited[child]) continue;
  49.         if (querydfs(child, node, depth + 1, val + (w >= median ? 1 : -1), median)) return true;
  50.     }
  51.     return false;
  52. }
  53. void updatedfs(const int &node, const int &parent, const int &depth, const int &val, const int &median) {
  54.     sgtupdate(depth, val, 0, 0, s);
  55.     for (auto &[child, w] : g[node]) {
  56.         if (child == parent || visited[child]) continue;
  57.         updatedfs(child, node, depth + 1, val + (w >= median ? 1 : -1), median);
  58.     }
  59. }
  60. pair <int, int> findcentroid(int node) {
  61.     int sz = subtsize[node] / 2, parent = -1;
  62.     bool cont = true;
  63.     while (cont) {
  64.         cont = false;
  65.         for (auto &[neigh, _] : g[node]) {
  66.             if (!visited[neigh] && neigh != parent && subtsize[neigh] > sz) {
  67.                 cont = true;
  68.                 parent = node;
  69.                 node = neigh;
  70.                 break;
  71.             }
  72.         }
  73.     }
  74.     return {node, parent};
  75. }
  76. bool searchpath(const int &root, const int &median) {
  77.     if (visited[root]) return false;
  78.     auto [centroid, centparent] = findcentroid(root);
  79.     visited[centroid] = true;
  80.     resetsgt[0] = true;
  81.     sgtupdate(0, 0, 0, 0, s);
  82.     for (auto &[neigh, w] : g[centroid]) {
  83.         if (visited[neigh]) continue;
  84.         if (querydfs(neigh, centroid, 1, w >= median ? 1 : -1, median)) {
  85.             // cerr << "FOUND!! " << centroid << ' ' << neigh << ' ' << median << '\n';
  86.             return true;
  87.         }
  88.         updatedfs(neigh, centroid, 1, w >= median ? 1 : -1, median);
  89.     }
  90.     if (centparent >= 0) calcsubt(centparent, -1);
  91.     for (auto &[neigh, _] : g[centroid]) {
  92.         if (searchpath(neigh, median)) return true;
  93.     }
  94.     return false;
  95. }
  96. // Dali postoi pat so medijana >= median
  97. bool ok(int median) {
  98.     memset(visited, 0, n * sizeof(bool));
  99.     calcsubt(0, -1);
  100.     return searchpath(0, median);
  101. }
  102. signed main() {
  103.     ios::sync_with_stdio(0);
  104.     cin.tie(0); cout.tie(0);
  105.     cin >> n >> L >> H;
  106.     s = (1 << int(ceil(log2(n + 5)))) - 1;
  107.     for (int i = 1, a, b, w; i < n; i++) {
  108.         cin >> a >> b >> w;
  109.         g[--a].push_back({--b, w});
  110.         g[b].push_back({a, w});
  111.     }
  112.     int l = 0, r = 15e8, m;
  113.         while (r - l > 1) {
  114.         m = l + r >> 1;
  115.         if (ok(m)) l = m;
  116.         else r = m;
  117.     }
  118.     // cerr << l << ' ' << r;
  119.     cout << (l != r && ok(r) ? r : l);
  120. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement