Advertisement
999ms

Untitled

Sep 24th, 2019
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.28 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define all(x) (x).begin(),(x).end()
  3.  
  4. using namespace std;
  5.  
  6. int n;
  7.  
  8. __inline__ int Level(int v) {
  9.     int x = 0;
  10.     while (v > 0) {
  11.         v >>= 1;
  12.         x++;
  13.     }
  14.     return x;
  15. }
  16.  
  17. __inline__ int Lca(int a, int b) {
  18.     if (Level(a) < Level(b)) swap(a, b);
  19.     while (Level(a) > Level(b)) a >>= 1;
  20.     while (a != b) {
  21.         a >>= 1;
  22.         b >>= 1;
  23.     }
  24.     return a;
  25. }
  26.  
  27. __inline__ bool isLeaf(int v) {
  28.     return v * 2 > n;
  29. }
  30.  
  31. unordered_set<int> connectedLeft;
  32. unordered_set<int> connectedRight;
  33. unordered_set<int> connectedBetween;
  34. unordered_set<int> good;
  35.  
  36. __inline__ void Check(int v) {
  37.     if (isLeaf(v)) return;
  38.     if (connectedLeft.count(v) + connectedRight.count(v) + connectedBetween.count(v) >= 2) {
  39.         good.insert(v);
  40.     } else if (connectedBetween.count(1)) {
  41.         good.insert(1);
  42.     }
  43. }
  44.  
  45. int main() {
  46.     ios_base::sync_with_stdio(false);
  47.     cin.tie(nullptr);
  48.     int m;
  49.     cin >> n >> m;
  50.     if (n <= 2) {
  51.         m++;
  52.         while (m--) {
  53.             cout << "0\n";
  54.         }
  55.         return 0;
  56.     }
  57.     int sum = 0;
  58.     int full = 1;
  59.     while (n >= full + sum) {
  60.         sum += full;
  61.         full <<= 1;
  62.     }
  63.     int rem = n - sum;
  64.     int lastFullLvl = (full >> 1);
  65.     int leaves = rem + (lastFullLvl - (rem + 1) / 2);
  66.     cout << n - leaves << "\n";
  67.     if (rem & 1) {
  68.         connectedRight.insert(sum - lastFullLvl + (rem + 1) / 2);
  69.     }
  70.     int a, b;
  71.     while (m--) {
  72.         cin >> a >> b;
  73.         if (a / 2 == b || b / 2 == a) {
  74.             cout << n - leaves - good.size() << "\n";
  75.             continue;
  76.         }
  77.         int c = Lca(a, b);
  78.         if (c != a && c != b) {
  79.             connectedBetween.insert(c);
  80.             Check(c);
  81.         }
  82.         while (a / 2 > c) {
  83.             if (a & 1) {
  84.                 connectedRight.insert(a / 2);
  85.             } else {
  86.                 connectedLeft.insert(a / 2);
  87.             }
  88.             Check(a / 2);
  89.             a /= 2;
  90.         }
  91.         while (b / 2 > c) {
  92.             if (b & 1) {
  93.                 connectedRight.insert(b / 2);
  94.             } else {
  95.                 connectedLeft.insert(b / 2);
  96.             }
  97.             Check(b / 2);
  98.             b /= 2;
  99.         }
  100.         cout << n - leaves - good.size() << "\n";
  101.     }
  102. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement