제출 #999532

#제출 시각아이디문제언어결과실행 시간메모리
999532cadmiumsky자리 배치 (IOI18_seats)C++17
100 / 100
2808 ms173012 KiB
#include <bits/stdc++.h>
#include "seats.h"
#define all(x) (x).begin(),(x).end()
using namespace std;
using pii = pair<int,int>;

#define sz(x) ((int)(x).size())

template<typename Node> 
struct AINT {
   vector<Node> aint;
   int n;
   void init(int n_) {
      n = n_;
      aint.assign(2 * n + 5, Node());
   }
   
   template<class CB> void walk(CB&& cb) { walk(cb, 0, n); }
   template<class CB> void walk(CB&& cb, int l, int r) { walk(cb, l, r, 1, 0, n); }
   template<class CB> void walk(CB&& cb, int l, int r, int node, int cl, int cr) {
      if(cr < l || r < cl) return;
      if(l <= cl && cr <= r && !cb(aint[node], cl, cr)) return;
      int mid = (cl + cr) >> 1, L = node + 1, R = node + (mid - cl + 1) * 2;
      aint[node].push(aint[L], aint[R]);
      walk(cb, l, r, L, cl, mid);
      walk(cb, l, r, R, mid + 1, cr);
      aint[node].pull(aint[L], aint[R]);
   }
};

const int necesar = 1;


struct nmns : pii {
   void pull(const nmns& L, const nmns& R) {
      first = min(L.first, R.first);
      second = (L.first == first) * L.second + (R.first == first) * R.second;
   }
   void apply(int x) { first += x; }
};

struct Node {
   nmns val;
   int lazy;
   void push(Node& L, Node& R) {
      if(lazy == 0) return;
      L.val.apply(lazy);
      R.val.apply(lazy);
      L.lazy += lazy;
      R.lazy += lazy;
      lazy = 0;
   }
   
   void pull(const Node& L, const Node& R) {
      val.pull(L.val, R.val);
   }
};

AINT<Node> aint;

void add(int l, int r, int val) { 
   aint.walk([&](Node& node, int cl, int cr) { node.val.apply(val); node.lazy += val; return 0;}, l, r); 
}
int query() { 
   //aint.walk([&](Node& node, int cl, int cr) {  cerr << "--\n";  for(auto [a, b] : node.val) cerr << '\t' << a << ": " << b << '\n'; cerr << "--\n"; return 0;}, 2, 2);
   auto v = aint.aint[1].val;
   //aint.walk([&](Node& val, int cl, int cr) {
      //if(cl != cr) return 1;
      //cerr << val.val[0].first << ": " << val.val[0].second << ",\t";
      //return 0; 
   //});
   //cerr << '\n';
   
   return v.second;
}

vector<vector<int>> mat;
vector<int> R, C;
int H, W;

vector<vector<int>> added;

void modcorner(int i, int j, int aggr) {
   if(added[i][j] == aggr) return;
   added[i][j] = aggr;
   vector<int> val;
   val.emplace_back(mat[i][j]);
   val.emplace_back(mat[i + 1][j]);
   val.emplace_back(mat[i + 1][j + 1]);
   val.emplace_back(mat[i][j + 1]);
   sort(all(val));
   add(val[0], val[1] - 1, aggr);
   add(val[2], val[3] - 1, aggr);
   return;
}


void modcell(int i, int j, int aggr) {
   for(int a = -1; a <= 1; a++)
      for(int b = -1; b <= 1; b++)
         if(i + a >= 0 && i + a <= H && j + b >= 0 && j + b <= W)
            modcorner(i + a, j + b, aggr);
}

void give_initial_chart(int H_, int W_, std::vector<int> R_, std::vector<int> C_) {
   H = H_; W = W_; R = R_; C = C_;
   mat.assign(H + 2, vector<int>(W + 2, H * W + 1));
   added.assign(H + 2, vector<int>(W + 2, 0));
   for(auto &x : R) x++;
   for(auto &x : C) x++;
   for(int i = 0; i < H * W; i++) mat[R[i]][C[i]] = i;
   aint.init(H * W - 1);
   aint.walk([&](Node& val, int cl, int cr) {
      if(cl != cr) return 1;
      val.val.first = 0;
      val.val.second = 1;
      return 0;
   });
   
   for(int i = 0; i <= H; i++)
      for(int j = 0; j <= W; j++)
         modcorner(i, j, 1);
}

int swap_seats(int a, int b) {
   auto [x, y] = make_pair(R[a], C[a]);
   auto [u, v] = make_pair(R[b], C[b]);
   swap(R[a], R[b]);
   swap(C[a], C[b]);
   modcell(x, y, -1);
   modcell(u, v, -1);
   swap(mat[x][y], mat[u][v]);
   modcell(x, y, 1);
   modcell(u, v, 1);
   return query();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...