Submission #1360492

#TimeUsernameProblemLanguageResultExecution timeMemory
1360492retardeSeats (IOI18_seats)C++20
5 / 100
4098 ms106356 KiB
#include "seats.h"
#include <bits/stdc++.h>
using namespace std;

class Segmin {
  private:
  int n;
  vector<int> a, seg;
  void build(int i, int l, int r) {
    if (l > r) return;
    if (l == r) {
      seg[i] = a[l];
      return;
    }
    int mid = (l + r) / 2;
    build(i * 2, l, mid);
    build(i * 2 + 1, mid + 1, r);
    seg[i] = min(seg[i * 2], seg[i * 2 + 1]);
  }
  int query(int i, int l, int r, int ql, int qr) {
    if (qr < l || r < ql) return 1e8;
    if (ql <= l && r <= qr) return seg[i];
    int mid = (l + r) / 2;
    return min(query(i * 2, l, mid, ql, qr), query(i * 2 + 1, mid + 1, r, ql, qr));
  }
  void upd(int i, int l, int r, int qi, int qv) {
    if (l == r) {
      seg[i] = a[l] = qv;
      return;
    }
    int mid = (l + r) / 2;
    if (qi <= mid) upd(i * 2, l, mid, qi, qv);
    else upd(i * 2 + 1, mid + 1, r, qi, qv);
    seg[i] = min(seg[i * 2], seg[i * 2 + 1]);
  }

  public:
  Segmin(vector<int> b) {
    n = (int)b.size();
    a = b; seg.resize(4 * n);
    build(1, 0, n - 1);
  }
  void build() { build(1, 0, n - 1); }
  int query(int l, int r) { return query(1, 0, n - 1, l, r); }
  int query(int i) { return query(1, 0, n - 1, i, i); }
  void upd(int qi, int qv) { upd(1, 0, n - 1, qi, qv); }
};

class Segmax {
  private:
  int n;
  vector<int> a, seg;
  void build(int i, int l, int r) {
    if (l > r) return;
    if (l == r) {
      seg[i] = a[l];
      return;
    }
    int mid = (l + r) / 2;
    build(i * 2, l, mid);
    build(i * 2 + 1, mid + 1, r);
    seg[i] = max(seg[i * 2], seg[i * 2 + 1]);
  }
  int query(int i, int l, int r, int ql, int qr) {
    if (qr < l || r < ql) return -1e8;
    if (ql <= l && r <= qr) return seg[i];
    int mid = (l + r) / 2;
    return max(query(i * 2, l, mid, ql, qr), query(i * 2 + 1, mid + 1, r, ql, qr));
  }
  void upd(int i, int l, int r, int qi, int qv) {
    if (l == r) {
      seg[i] = a[l] = qv;
      return;
    }
    int mid = (l + r) / 2;
    if (qi <= mid) upd(i * 2, l, mid, qi, qv);
    else upd(i * 2 + 1, mid + 1, r, qi, qv);
    seg[i] = max(seg[i * 2], seg[i * 2 + 1]);
  }

  public:
  Segmax(vector<int> b) {
    n = (int)b.size();
    a = b; seg.resize(4 * n);
    build(1, 0, n - 1);
  }
  void build() { build(1, 0, n - 1); }
  int query(int l, int r) { return query(1, 0, n - 1, l, r); }
  int query(int i) { return query(1, 0, n - 1, i, i); }
  void upd(int qi, int qv) { upd(1, 0, n - 1, qi, qv); }
};

Segmin l({}), u({});
Segmax r({}), d({});
vector<int> X, Y;
int h, w;

int minX(int x) {
  return l.query(0, x);
}
int maxX(int x) {
  return r.query(0, x);
}
int minY(int x) {
  return u.query(0, x);
}
int maxY(int x) {
  return d.query(0, x);
}

int good(int sz) {

  return ((maxX(sz-1)-minX(sz-1)+1)*(maxY(sz-1)-minY(sz-1)+1)) == sz;

  pair<int, int> xb = {minX(sz - 1), maxX(sz - 1)};
  pair<int, int> yb = {minY(sz - 1), maxY(sz - 1)};
  pair<int, int> xba = {min(l.query(0), l.query(sz-1)), max(r.query(0), r.query(sz-1))};
  pair<int, int> yba = {min(u.query(0), u.query(sz-1)), max(d.query(0), d.query(sz-1))};
  // cout << "checking size\n";
  // cout << "xb:\n";
  // cout << xb.first << " " << xb.second << '\n';
  // cout << "xba:\n";
  // cout << xba.first << " " << xba.second << '\n';

  // cout << "yb:\n";
  // cout << yb.first << " " << yb.second << '\n';
  // cout << "yba:\n";
  // cout << yba.first << " " << yba.second << '\n';
  return (xb == xba && yb == yba);
}

int ans() {
  // cout << "finding ans\n";
  int answ = 0;
  pair<int, int> xbound = {l.query(0), l.query(0)};
  pair<int, int> ybound = {u.query(0), d.query(0)};

  // cout << "X:\n";
  // for (int i = 0; i < h*w; i++) cout << l.query(i) << " ";
  // cout << '\n';
  // cout << "Y:\n";
  // for (int i = 0; i < h*w; i++) cout << d.query(i) << " ";
  // cout << '\n';

  int lst = -1;
  while (true) {
    // is this good?
    int sz = (xbound.second-xbound.first+1)*(ybound.second-ybound.first+1);
    assert(sz != lst);
    // cout << sz << " size\n";
    // cout << xbound.first+1 << " -> " << xbound.second+1 << '\n';
    // cout << ybound.first+1 << " -> " << ybound.second+1 << '\n';
    if (good(sz)) {
      // cout << "yezzir\n";
      answ++;
    }
    if (sz == h*w) break;
    xbound = {minX(sz), maxX(sz)};
    ybound = {minY(sz), maxY(sz)};
    lst = sz;
  }
  return answ;
}

void give_initial_chart(int H, int W, std::vector<int> R, std::vector<int> C) {
  X.resize(H * W); Y.resize(H * W);
  h = H; w = W; for (int i = 0; i < H*W; i++) {
    X[i] = C[i];
    Y[i] = R[i];
  }
  l = Segmin(X); r = Segmax(X);
  u = Segmin(Y); d = Segmax(Y);
  // cout << "done initial\n";
}

int swap_seats(int a, int b) {
  int oldxa = X[a];
  l.upd(a, X[b]); r.upd(a, X[b]);
  l.upd(b, oldxa); r.upd(b, oldxa);
  int oldya = Y[a];
  u.upd(a, Y[b]); d.upd(a, Y[b]);
  u.upd(b, oldya); d.upd(b, oldya);
  swap(X[a], X[b]);
  swap(Y[a], Y[b]);
  // cout << "done swap\n";
  return ans();
}

/*
2 3 2
0 0
1 0
1 1
0 1
0 2
1 2
0 5
0 5
*/
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...