Advertisement
vlatkovski

seating - jan 2013 gold

Apr 4th, 2021 (edited)
678
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.04 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int N = 500500;
  5. const int N2 = 1<<20;
  6.  
  7. const int NOLAZY = 0;
  8. const int EMPTY = 1;
  9. const int FULL = 2;
  10. const int MIXED = 3;
  11.  
  12. const int DYNAMIC = 0;
  13. const int PREFIX = 1;
  14. const int SUFFIX = 2;
  15.  
  16. struct Node {
  17.     int mx, pre, suf, status, lazy;
  18.     Node() {}
  19.     inline void push(Node &l, Node &r, int tl, int tr) {
  20.         int tm = (tl + tr) / 2;
  21.         if (lazy == EMPTY) {
  22.             l.mx = l.pre = l.suf = tm-tl+1;
  23.             r.mx = r.pre = r.suf = tr-tm;
  24.         } else if (lazy == FULL) {
  25.             l.mx = l.pre = l.suf = 0;
  26.             r.mx = r.pre = r.suf = 0;
  27.         }
  28.         l.status = l.lazy = lazy;
  29.         r.status = r.lazy = lazy;
  30.         lazy = NOLAZY;
  31.     }
  32.     inline void pull(Node &l, Node &r) {
  33.         if (l.status == EMPTY && r.status == EMPTY) {
  34.             status = EMPTY;
  35.             mx = pre = suf = l.mx + r.mx;
  36.         } else if (l.status == FULL && r.status == FULL) {
  37.             status = FULL;
  38.             mx = pre = suf = 0;
  39.         } else {
  40.             status = MIXED;
  41.             pre = l.pre;
  42.             suf = r.suf;
  43.             mx = 0;
  44.             if (l.mx > mx) {
  45.                 mx = l.mx;
  46.             }
  47.             if (r.mx > mx) {
  48.                 mx = r.mx;
  49.             }
  50.             if (l.suf + r.pre > mx) {
  51.                 mx = l.suf + r.pre;
  52.             }
  53.         }
  54.     }
  55. };
  56.  
  57. Node tree[N2];
  58.  
  59. void build(int v, int tl, int tr) {
  60.     tree[v].lazy = NOLAZY;
  61.     if (tl == tr) {
  62.         tree[v].mx = tree[v].pre = tree[v].suf = 1;
  63.         tree[v].status = EMPTY;
  64.     } else {
  65.         int tm = (tl + tr) / 2;
  66.         build(2*v, tl, tm);
  67.         build(2*v+1, tm+1, tr);
  68.         tree[v].pull(tree[2*v], tree[2*v+1]);
  69.     }
  70. }
  71.  
  72. pair<int, int> findrange(int v, int tl, int tr, int p, int status) {
  73.     if (tree[v].mx < p) {
  74.         return make_pair(-1, -1);
  75.     }
  76.     if (tl == tr) {
  77.         // leaf
  78.         return make_pair(tl, tl);
  79.     }
  80.     if (tr-tl+1 == p) {
  81.         // perfect fit
  82.         return make_pair(tl, tr);
  83.     }
  84.     // must either go down or split
  85.     int tm = (tl + tr) / 2;
  86.     tree[v].push(tree[2*v], tree[2*v+1], tl, tr);
  87.     if (status == DYNAMIC) {
  88.         if (tree[2*v].mx >= p) {
  89.             // completely in left child
  90.             return findrange(2*v, tl, tm, p, DYNAMIC);
  91.         } else if (tree[2*v+1].mx >= p) {
  92.             // completely in right child
  93.             return findrange(2*v+1, tm+1, tr, p, DYNAMIC);
  94.         } else {
  95.             // mx = l.suf + r.pre >= p
  96.             // using suffix of left, prefix of right
  97.             int l = findrange(2*v, tl, tm, tree[2*v].suf, SUFFIX).first;
  98.             int r = findrange(2*v+1, tm+1, tr, p-tree[2*v].suf, PREFIX).second;
  99.             return make_pair(l, r);
  100.         }
  101.     } else if (status == PREFIX) {
  102.         if (tree[2*v].pre >= p) {
  103.             // completely in left
  104.             return findrange(2*v, tl, tm, p, PREFIX);
  105.         } else {
  106.             // using whole left, prefix of right
  107.             // l.mx == l.pre
  108.             return findrange(2*v+1, tm+1, tr, p-tree[2*v].mx, PREFIX);
  109.         }
  110.     } else if (status == SUFFIX) {
  111.         if (tree[2*v+1].suf >= p) {
  112.             // completely in right
  113.             return findrange(2*v+1, tm+1, tr, p, SUFFIX);
  114.         } else {
  115.             // using prefix of left, whole right
  116.             // r.mx == r.suf
  117.             return findrange(2*v, tl, tm, p-tree[2*v+1].mx, SUFFIX);
  118.         }
  119.     } else {
  120.         //cout << "Error.\n";
  121.         return make_pair(-1, -1);
  122.     }
  123. }
  124.  
  125. void update(int v, int tl, int tr, int l, int r, int val) {
  126.     if (l > r) return;
  127.     if (l == tl && tr == r) {
  128.         if (val == 0) {
  129.             // leaving
  130.             tree[v].mx = tree[v].pre = tree[v].suf = tr-tl+1;
  131.             tree[v].status = tree[v].lazy = EMPTY;
  132.         } else {
  133.             // arriving
  134.             tree[v].mx = tree[v].pre = tree[v].suf = 0;
  135.             tree[v].status = tree[v].lazy = FULL;
  136.         }
  137.         return;
  138.     }
  139.     tree[v].push(tree[2*v], tree[2*v+1], tl, tr);
  140.     int tm = (tl + tr) / 2;
  141.     update(2*v, tl, tm, l, min(r, tm), val);
  142.     update(2*v+1, tm+1, tr, max(l, tm+1), r, val);
  143.     tree[v].pull(tree[2*v], tree[2*v+1]);
  144. }
  145.  
  146. int main() {
  147.     ios::sync_with_stdio(false);
  148.     cin.tie(0);
  149.     #ifndef _DEBUG
  150.     freopen("seating.in", "r", stdin);
  151.     freopen("seating.out", "w", stdout);
  152.     #endif
  153.     int n, m;
  154.     cin >> n >> m;
  155.     int ans = 0;
  156.     build(1, 1, n);
  157.     while (m--) {
  158.         char ch;
  159.         cin >> ch;
  160.         if (ch == 'A') {
  161.             int p, l, r;
  162.             cin >> p;
  163.             tie(l, r) = findrange(1, 1, n, p, DYNAMIC);
  164.             if (l == -1 || r == -1) {
  165.                 ans += 1;
  166.             } else {
  167.                 update(1, 1, n, l, r, 1);
  168.             }
  169.         } else {
  170.             int l, r;
  171.             cin >> l >> r;
  172.             update(1, 1, n, l, r, 0);
  173.         }
  174.     }
  175.     cout << ans << '\n';
  176. }
  177.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement