EntropyIncreaser

SHOI2015 脑洞治疗仪

Dec 5th, 2017
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.09 KB | None | 0 0
  1. #include <cstdio>
  2.  
  3. #include <algorithm>
  4.  
  5. #define LOG(FMT...) fprintf(stderr, FMT)
  6.  
  7. using namespace std;
  8.  
  9. struct data {
  10.     int l, r;
  11.     int sum, lmex, rmex, mex;
  12.  
  13.     data() {}
  14.  
  15.     data(int l, int r, int x) : l(l), r(r), sum(x), lmex(x), rmex(x), mex(x) {}
  16.  
  17.     data operator+(const data& x) const;
  18.  
  19.     bool full() const;
  20. };
  21.  
  22. struct node {
  23.     data d;
  24.     int lazy;
  25.     node *ls, *rs;
  26.  
  27.     int bound(int l, int& x);
  28.     data query(int l, int r);
  29.     void change(int l, int r, int x);
  30.  
  31.     void push_down();
  32.     void update();
  33.     data get_d() const;
  34. };
  35.  
  36. const int N = 200010;
  37.  
  38. int n, m;
  39. node* root;
  40.  
  41. node* build(int l, int r);
  42.  
  43. int main() {
  44.     int op, l, r, l2, r2, x, y;
  45.     scanf("%d%d", &n, &m);
  46.     root = build(1, n);
  47.     while (m--) {
  48.         scanf("%d%d%d", &op, &l, &r);
  49.         switch (op) {
  50.         case 0:
  51.             root->change(l, r, 1);
  52.             break;
  53.         case 1:
  54.             scanf("%d%d", &l2, &r2);
  55.             x = r - l + 1 - root->query(l, r).sum;
  56.             root->change(l, r, 1);
  57.             y = min(root->bound(l2, x), r2);
  58.             if (y >= l2)
  59.                 root->change(l2, y, 0);
  60.             break;
  61.         case 2:
  62.             printf("%d\n", root->query(l, r).mex);
  63.             break;
  64.         }
  65.     }
  66.     return 0;
  67. }
  68.  
  69. node* build(int l, int r) {
  70.     static node pool[N << 1];
  71.     static int cnt;
  72.     node* p = pool + ++cnt;
  73.     p->d = data(l, r, 0);
  74.     if (l == r)
  75.         return p;
  76.     int mid = (l + r) >> 1;
  77.     p->ls = build(l, mid);
  78.     p->rs = build(mid + 1, r);
  79.     return p;
  80. }
  81.  
  82. data node::query(int l, int r) {
  83.     if (d.l == l && d.r == r)
  84.         return get_d();
  85.     push_down();
  86.     if (r <= ls->d.r)
  87.         return ls->query(l, r);
  88.     if (l >= rs->d.l)
  89.         return rs->query(l, r);
  90.     return ls->query(l, ls->d.r) + rs->query(rs->d.l, r);
  91. }
  92.  
  93. void node::change(int l, int r, int x) {
  94.     if (d.l == l && d.r == r) {
  95.         lazy = x;
  96.         return;
  97.     }
  98.     push_down();
  99.     if (r <= ls->d.r)
  100.         ls->change(l, r, x);
  101.     else if (l >= rs->d.l)
  102.         rs->change(l, r, x);
  103.     else {
  104.         ls->change(l, ls->d.r, x);
  105.         rs->change(rs->d.l, r, x);
  106.     }
  107.     update();
  108. }
  109.  
  110. int node::bound(int l, int& x) {
  111.     if (!x)
  112.         return l - 1;
  113.     push_down();
  114.     if (d.l == l) {
  115.         if (d.sum <= x) {
  116.             x -= d.sum;
  117.             return d.r;
  118.         }
  119.         int ret = ls->bound(l, x);
  120.         if (!x)
  121.             return ret;
  122.         return rs->bound(rs->d.l, x);
  123.     }
  124.     if (ls->d.r >= l) {
  125.         int ret = ls->bound(l, x);
  126.         if (!x)
  127.             return ret;
  128.         return rs->bound(rs->d.l, x);
  129.     }
  130.     return rs->bound(l, x);
  131. }
  132.  
  133. void node::push_down() {
  134.     switch (lazy) {
  135.     case 0:
  136.         d.sum = d.lmex = d.rmex = d.mex = 0;
  137.         break;
  138.     case 1:
  139.         d.sum = d.lmex = d.rmex = d.mex = d.r - d.l + 1;
  140.         break;
  141.     default:
  142.         return;
  143.     }
  144.     if (ls)
  145.         ls->lazy = rs->lazy = lazy;
  146.     lazy = 2;
  147. }
  148.  
  149. void node::update()
  150. { d = ls->get_d() + rs->get_d(); }
  151.  
  152. data node::get_d() const {
  153.     if (lazy == 0)
  154.         return data(d.l, d.r, 0);
  155.     if (lazy == 1)
  156.         return data(d.l, d.r, d.r - d.l + 1);
  157.     return d;
  158. }
  159.  
  160. data data::operator+(const data& x) const {
  161.     data ret;
  162.     ret.l = l;
  163.     ret.r = x.r;
  164.     ret.sum = sum + x.sum;
  165.     if (full())
  166.         ret.lmex = sum + x.lmex;
  167.     else
  168.         ret.lmex = lmex;
  169.     if (x.full())
  170.         ret.rmex = rmex + x.sum;
  171.     else
  172.         ret.rmex = x.rmex;
  173.     ret.mex = max(max(mex, x.mex), rmex + x.lmex);
  174.     return ret;
  175. }
  176.  
  177. bool data::full() const
  178. { return sum == r - l + 1; }
Advertisement
Add Comment
Please, Sign In to add comment