列表

详情


NC15208. 寻找车位

描述

access_globe 有一个巨大的停车场,这个停车场有 n 行,每行有 m 个车位。为了美观,access_globe 在建立这个停车场时,规定这个停车场必须是长条形的,即 n ≥m。每个车位都是一个正方形的区域。
最近,access_globe 正在为抽不到 Missing Poster 而苦恼,因此他请你帮他维护这个停车场。你需要支持两个个事件:
- 一辆车停到某一个车位中,或一辆车从某个车位开走
- 查询一个矩形区域内最大的只包含空车位的正方形区域
如果你能帮 access_globe 高效地解决这个问题,access_globe 一定会好好奖励你的。

输入描述

第一行包含三个正整数 n、m、q,表示停车场的大小和事件的个数;
接下来 n 行,每行 m 个 0 或 1 的数,如果第 i 行第 j 的数为 1,则表示第 i 行第 j 列的车位为空,否则表示这个车位非空;
接下来 q 行,每行表示一个事件,有以下两种形式:
- 0 x y :第 x 行第 y 列的车位的停车情况改变,即若此事件发生前这个车位为空,则此事件后这个车位非空,否则此事件后这个车位为空,保证 1≤ x≤ n,1≤ y≤ m
- 1 l s r t:询问以 (l, s) 和 (r,t) 为对角的矩形区域中,最大的全空正方形区域的边长,保证 1≤ l≤ r≤ n,1≤ s≤ t≤ m

输出描述

对每个询问输出一行一个整数,表示该询问的全空正方形的边长。

示例1

输入:

5 4 10
1 1 1 0
1 1 1 1
1 1 0 1
1 0 1 0
1 1 0 0
1 1 1 5 4
1 3 1 3 1
1 3 3 3 3
1 2 3 5 3
0 2 2
1 1 4 2 4
1 1 3 3 3
0 5 1
1 2 3 2 4
1 1 2 2 4

输出:

2
1
0
1
1
1
1
1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 54ms, 内存消耗: 7784K, 提交时间: 2019-01-07 18:01:02

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <cassert>
#include <map>
using namespace std;
#define RG register
#define IL __inline__ __attribute__((always_inline))
#define For(i, a, b) for(RG int i = a, ___u = b; i <= ___u; ++i)
#define Dor(i, a, b) for(RG int i = b, ___d = a; i >= ___d; --i)
#define Rep(i, a, b) for(RG int i = a, ___u = b; i != ___u; ++i)
#define dmin(a, b) ((a) < (b) ? (a) : (b))
#define dmax(a, b) ((a) > (b) ? (a) : (b))
#define cmin(a, b) ((a) > (b) ? (a) = (b), 1 : 0)
#define cmax(a, b) ((a) < (b) ? (a) = (b), 1 : 0)
#define diff(a, b) ((a) > (b) ? (a) - (b) : (b) - (a))
#define dabs(i) ((i) > 0 ? (i) : -(i))
typedef long long ll;
typedef unsigned uint;
typedef unsigned long long ull;
typedef long double ld;

#include <set>

namespace pb_ds
{   
 // 输入输出优化模板从此开始
 namespace io
 {
  const int MaxBuff = 1 << 20;
  const int Output = 1 << 24;
  char B[MaxBuff], *S = B, *T = B;
  //#define getc() getchar()
  #define getc() ((S == T) && (T = (S = B) + fread(B, 1, MaxBuff, stdin), S == T) ? 0 : *S++)
  char Out[Output], *iter = Out;
  IL void flush()
  {
   fwrite(Out, 1, iter - Out, stdout);
   iter = Out;
  }
 }
 
 template<class Type> IL Type read()
 {
  using namespace io;
  RG char ch; RG Type ans = 0; RG bool neg = 0;
  while(ch = getc(), (ch < '0' || ch > '9') && ch != '-')  ;
  ch == '-' ? neg = 1 : ans = ch - '0';
  while(ch = getc(), '0' <= ch && ch <= '9') ans = ans * 10 + ch - '0';
  return neg ? -ans : ans;
 }
 template<class Type> IL void print(RG Type x, RG char ch = '\n')
 {
  using namespace io;
  if(!x) *iter++ = '0';
  else
  {
   if(x < 0) *iter++ = '-', x = -x;
   static int S2[100]; RG int t = 0;
   while(x) S2[++t] = x % 10, x /= 10;
   while(t) *iter++ = '0' + S2[t--];
  }
  *iter++ = ch;
 }
 // 输入输出优化模板到此结束
 
 const int MaxN = 2010;
 const int MaxS = MaxN * MaxN;
 
 int int_mem[MaxS * 7 + MaxN], *int_tot = int_mem;
 int *map[MaxS];
 int N, M;
 
 typedef const int * const cintarr;

 
 int *__val__;
  
 int qp, ql, qr, qs, qt, qans, qmans;
 
 struct Data{int v, p;} lq[MaxN], rq[MaxN];
 IL void calc_val(RG const int m, RG cintarr L, RG cintarr R, RG int* const val = __val__)
 {
  if(!L || !R) // leaf
  {
   memcpy(val + qs, map[m] + qs, (qt - qs + 1) << 2);
   return;
  }
  RG const int lmax = m - ql + 1, rmax = qr - m;
  RG int lh = 1, lt = 0, rh = 1, rt = 0, k = qs - 1;
  RG Data d;
  For(i, qs, qt)
  {
   d = (Data) {dmin(lmax, L[i]), i}; while(lh <= lt && lq[lt].v >= d.v) --lt; lq[++lt] = d;
   d = (Data) {dmin(rmax, R[i]), i}; while(rh <= rt && rq[rt].v >= d.v) --rt; rq[++rt] = d;
   while(k != i && i - k > lq[lh].v + rq[rh].v)
   {
    ++k;
    (lq[lh].p == k) ? ++lh : 0;
    (rq[rh].p == k) ? ++rh : 0;
   }
   val[i] = i - k;
  }
 }
 #define cmaxmax(a, b, c) ((b) > (c) ? cmax(a, b) : cmax(a, c))
 #define cmaxmin(a, b, c) ((b) < (c) ? cmax(a, b) : cmax(a, c))
 IL void query_val(RG cintarr val = __val__)
 {
  For(i, qs, qt) cmaxmin(qans, val[i], i - qs + 1);
 }
 
 struct SNode *tot;
 struct SNode
 {
  int l, r, m;
  int *lval, *rval, *val, max_ans;
  SNode *pl, *pr;
  
  IL void save()
  {
   calc_val(m, pl ? pl->rval : 0, pr ? pr->lval : 0, val);
   qans = (l != r ? dmax(pl->max_ans, pr->max_ans) : 0); 
   query_val(val); max_ans = qans;
   if(l == r)
   {
    memcpy(lval + 1, val + 1, M << 2);
    memcpy(rval + 1, val + 1, M << 2);
    return;
   }
   RG int lmax = m - l + 1, rmax = r - m;
   RG cintarr pll = pl->lval, plr = pl->rval, plv = pl->val;
   RG cintarr prl = pr->lval, prr = pr->rval, prv = pr->val;
   For(i, 1, M)
   {
    cmaxmax(val[i], plv[i], prv[i]);
    lval[i] = (pll[i] == lmax ? lmax + prl[i] : pll[i]);
    rval[i] = (prr[i] == rmax ? rmax + plr[i] : prr[i]);
   }
  }
  
  void build(RG int _l = 1, RG int _r = N)
  {
   l = _l, r = _r, m = (l + r) >> 1;
   lval = int_tot; int_tot += M;
   rval = int_tot; int_tot += M;
   val = int_tot; int_tot += M;
   if(l != r)
   {
    (pl = ++tot)->build(l, m);
    (pr = ++tot)->build(m + 1, r);
   }
   save();
  }
  void modify()
  {
   (l != r) ? (qp <= m ? pl : pr)->modify() : void(0); 
   save();
  }
  void query()
  {
   if(ql <= l && r <= qr)
    return query_val(val);
   (ql <= m && m < qr) 
    ? (calc_val(m, pl->rval, pr->lval), query_val())
    : void(0);
   #define PLQ (ql <= m && qans < dmin(qmans, pl->max_ans) ? pl->query() : void(0))
   #define PRQ (m <  qr && qans < dmin(qmans, pr->max_ans) ? pr->query() : void(0))
   (pl->max_ans > pr->max_ans) ? (PLQ, PRQ) : (PRQ, PLQ);
  }
 } mem[MaxS * 2];
 
 
 IL void main()
 {
  RG int (*F)() = read<int>;
  N = F(), M = F();
  RG int Q = F();
  __val__ = int_tot;
  int_tot += M;
  For(i, 1, N) 
  {
   map[i] = int_tot;
   int_tot += M;
   For(j, 1, M) map[i][j] = F();
  }
  RG SNode *T = tot = mem;
  qs = 1;
  qt = M;
  ql = 1;
  qr = N;
  T->build();
  
  while(Q--)
   if(F()) // query
   {
    ql = F();
    qs = F();
    qr = F();
    qt = F();
    qans = 0;
    qmans = dmin(qr - ql + 1, qt - qs + 1);
    T->query();
    print(qans);
   }
   else // mod
   {
    qp = F();
    map[qp][F()] ^= 1;
    qs = 1;
    qt = M;
    ql = 1;
    qr = N;
    T->modify();
   }
  io::flush();
 }
}

int main()
{
 pb_ds::main();
 fclose(stdin), fclose(stdout);  
}

上一题