Problem:
Problem K: Escape of Lappin the Phantom Thief
Problem
怪盗ラッパンは宝石を盗みにやってきた。簡単に宝石を手にすることができたが、宝石にはセンサーが仕込まれており、警備ロボットに囲まれてしまった。
警備ロボットは宝石に向かって移動するように仕組まれている。センサーは簡単に外せそうになかったので、宝石を置いて逃走することにした。宝石をできるだけ警備ロボットから遠くに置いて、逃げるための時間稼ぎをすることにした。
敷地は
n
×
m
のマスからなる長方形の形をしていて、障害物はない。
k
体の警備ロボットは、それぞれマス(
x
i
,
y
i
)(0 ≤
x
i
≤
n
−1, 0 ≤
y
i
≤
m
−1)に配置されており、上下左右のマスに単位時間で移動できる。
警備ロボットは宝石があるマスに最短経路で移動する。
敷地内に自由に宝石を置けるとき、1台以上の警備ロボットが宝石のあるマスに到達するまでにかかる移動時間の最大値を求めよ。
Input
n
m
k
x
1
y
1
x
2
y
2
...
x
k
y
k
入力はすべて整数で与えられる。
1行目に
n
,
m
,
k
が空白区切りで与えられる。
2行目以降
k
行に警備ロボットのいるマスの座標(
x
i
,
y
i
)が空白区切りで与えられる。
Constraints
1 ≤
n
,
m
≤ 5 × 10
4
1 ≤
k
≤ min(10
5
,
n
×
m
)
0 ≤
x
i
≤
n
−1
0 ≤
y
i
≤
m
−1
与えられる座標はすべて異なる
Output
警備ロボットが到達するまでに、最も時間がかかる場所への移動時間を1行に出力せよ。
Sample Input 1
20 10 1
0 0
Sample Output 1
28
Sample Input 2
20 10 2
0 0
17 5
Sample Output 2
15
Sample Input 3
20 10 3
0 0
17 5
6 9
Sample Output 3
11

Submitted solutions:

code_snippet: // AOJ #1597 Escape of Lappin the Phantom Thief
// 2025.2.23

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

struct Robot { int x, y, u, v; };

struct Event { int v, L, R, delta; };

struct SegTree {
    int n;
    vector<int> tree, lazy;
    SegTree(int n) : n(n) {
        tree.assign(4 * n, 0);
        lazy.assign(4 * n, 0);
    }
    void push(int idx, int l, int r) {
        if(lazy[idx] != 0) {
            tree[idx] += lazy[idx];
            if(l != r) {
                lazy[idx*2] += lazy[idx];
                lazy[idx*2+1] += lazy[idx];
            }
            lazy[idx] = 0;
        }
    }
    void update(int idx, int l, int r, int ql, int qr, int val) {
        push(idx, l, r);
        if(qr < l || r < ql) return;
        if(ql <= l && r <= qr) {
            lazy[idx] += val;
            push(idx, l, r);
            return;
        }
        int mid = (l + r) / 2;
        update(idx*2, l, mid, ql, qr, val);
        update(idx*2+1, mid+1, r, ql, qr, val);
        tree[idx] = min(tree[idx*2], tree[idx*2+1]);
    }
    int query(int idx, int l, int r, int ql, int qr) {
        push(idx, l, r);
        if(qr < l || r < ql) return INT_MAX;
        if(ql <= l && r <= qr) return tree[idx];
        int mid = (l + r) / 2;
        return min(query(idx*2, l, mid, ql, qr), query(idx*2+1, mid+1, r, ql, qr));
    }
};

int n, m, k;
vector<Robot> robots;

vector<int> evenU, oddU;

void getUInterval(int v, int n, int m, int U_max, int &L, int &R) {
    L = max({0, -v, v});
    R = min({U_max, 2*n - 2 - v, 2*m - 2 + v});
}

bool feasible(int d) {
    if(d == 0) return true;
    int r = d - 1;
    int U_max = n + m - 2;
    int v_min = -(m - 1), v_max = n - 1;

    vector<Event> events;
    for (int i = 0; i < k; i++) {
        int rv = robots[i].v;
        int ru = robots[i].u;
        int v_low = max(v_min, rv - r);
        int v_high = min(v_max, rv + r);
        if(v_low > v_high) continue;
        int L = max(0, ru - r);
        int R = min(U_max, ru + r);
        events.push_back({v_low, L, R, +1});
        events.push_back({v_high + 1, L, R, -1});
    }
    sort(events.begin(), events.end(), [](const Event &a, const Event &b){
        return a.v < b.v;
    });

    SegTree segEven(evenU.size());
    SegTree segOdd(oddU.size());

    auto updateParity = [&](int L, int R, int delta) {
        int li = (int)(lower_bound(evenU.begin(), evenU.end(), L) - evenU.begin());
        int ri = (int)(upper_bound(evenU.begin(), evenU.end(), R) - evenU.begin()) - 1;
        if(li <= ri) {
            segEven.update(1, 0, evenU.size()-1, li, ri, delta);
        }
        li = (int)(lower_bound(oddU.begin(), oddU.end(), L) - oddU.begin());
        ri = (int)(upper_bound(oddU.begin(), oddU.end(), R) - oddU.begin()) - 1;
        if(li <= ri) {
            segOdd.update(1, 0, oddU.size()-1, li, ri, delta);
        }
    };

    int evIdx = 0;
    for (int v = v_min; v <= v_max; v++) {
        while(evIdx < (int)events.size() && events[evIdx].v == v) {
            updateParity(events[evIdx].L, events[evIdx].R, events[evIdx].delta);
            evIdx++;
        }
        int L0, R0;
        getUInterval(v, n, m, U_max, L0, R0);
        if(L0 > R0) continue;
        int parity = v & 1;
        int effectiveL = (L0 % 2 == parity ? L0 : L0 + 1);
        int effectiveR = (R0 % 2 == parity ? R0 : R0 - 1);
        if(effectiveL > effectiveR) continue;

        if(v % 2 == 0) {
            int li = (int)(lower_bound(evenU.begin(), evenU.end(), effectiveL) - evenU.begin());
            int ri = (int)(upper_bound(evenU.begin(), evenU.end(), effectiveR) - evenU.begin()) - 1;
            if(li <= ri) {
                int mn = segEven.query(1, 0, evenU.size()-1, li, ri);
                if(mn == 0) return true;
            }
        } else {
            int li = (int)(lower_bound(oddU.begin(), oddU.end(), effectiveL) - oddU.begin());
            int ri = (int)(upper_bound(oddU.begin(), oddU.end(), effectiveR) - oddU.begin()) - 1;
            if(li <= ri) {
                int mn = segOdd.query(1, 0, oddU.size()-1, li, ri);
                if(mn == 0) return true;
            }
        }
    }
    return false;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> n >> m >> k;
    robots.resize(k);
    for (int i = 0; i < k; i++){
        cin >> robots[i].x >> robots[i].y;
        robots[i].u = robots[i].x + robots[i].y;
        robots[i].v = robots[i].x - robots[i].y;
    }
    int U_max = n + m - 2;
    for (int u = 0; u <= U_max; u++){
        if(u % 2 == 0) evenU.push_back(u);
        else oddU.push_back(u);
    }

    int low = 0, high = n + m;
    while(low < high) {
        int mid = (low + high) / 2;
        if(feasible(mid)) low = mid + 1;
        else high = mid;
    }
    cout << low-1 << endl;
    return 0;
}
accuracy: 1
time_ms: 2300
memory_kb: 12588
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
struct edge{
  int p,l,r,f;
  edge(int p,int l,int r,int f):p(p),l(l),r(r),f(f){}
  bool operator<(const edge e)const{
    return p<e.p;
  }
};
vector<P> v;
vector<edge> e;
int n,m,k;
static const int MAX_SIZE = 1 << 17; 
int segMin[2][2 * MAX_SIZE - 1], segAdd[2][2 * MAX_SIZE - 1];
void add(int a, int b, int x, int w, int k = 0, int l = 0, int r = MAX_SIZE){
  if(a<0) a=0;
  if(b>MAX_SIZE) b=MAX_SIZE;
  if (r <= a || b <= l) return; 
  if (a <= l && r <= b){
    segAdd[w][k] += x;
    return;
  }
  add(a, b, x, w, k * 2 + 1, l, (l + r) / 2);
  add(a, b, x, w, k * 2 + 2, (l + r) / 2, r);
  segMin[w][k] = min(segMin[w][k * 2 + 1] + segAdd[w][k * 2 + 1],
		     segMin[w][k * 2 + 2] + segAdd[w][k * 2 + 2]);
}

int getMin(int a, int b, int w, int k = 0, int l = 0, int r = MAX_SIZE){
  if(a<0) a=0;
  if(b>MAX_SIZE) b=MAX_SIZE;
  if (r <= a || b <= l) return (MAX_SIZE);
  if (a <= l && r <= b) return (segMin[w][k] + segAdd[w][k]); 
  int left = getMin(a, b, w, k * 2 + 1, l, (l + r) / 2);
  int right = getMin(a, b, w, k * 2 + 2, (l + r) / 2, r);
  return (min(left, right) + segAdd[w][k]); 
}

bool check(int d){
  memset(segAdd,0,sizeof(segAdd));
  memset(segMin,0,sizeof(segMin));
  int i,j,a,b=0,g=d-1,p,q;
  e.clear();
  for(i=0;i<v.size();i++){
    int x=v[i].first,y=v[i].second;
    e.push_back(edge(x+y-d,n+y-x-d,n+y-x+d,1));
    e.push_back(edge(x+y+d+2,n+y-x-d,n+y-x+d,-1));
    e.push_back(edge(x+y-g,n+y-x-g,n+y-x+g,1));
    e.push_back(edge(x+y+g+2,n+y-x-g,n+y-x+g,-1));
  }
  //for(i=0;i<e.size();i++) cout << i << ":" << e[i].p <<":"<< e[i].l <<":"<< e[i].r <<":"<< e[i].f << endl;
  if(n%2){
    for(i=0;i<n+m;i++) add(i,i+1,MAX_SIZE,i%2);
  }else{
    for(i=0;i<n+m;i++) add(i,i+1,MAX_SIZE,(i+1)%2);
  }
  
  sort(e.begin(),e.end());
  for(i=0;i<e.size();i++){
    j=e[i].p;
    for(a=b;a<min(j,n+m-1);a++){
      if(a<n) p=a;
      else p=2*(n-1)-a;
      if(a<m) q=a;
      else q=2*(m-1)-a;
      int l=max(0,n-p),r=min(n+m-1,n+q);
      //cout << a << ":" << l << ":" << r << ":" << getMin(l,r+1,a%2) << endl;
      if(getMin(l,r+1,a%2)==0) return true;
    }
    while(1){
      if(i==e.size()||j!=e[i].p) break;
      add(e[i].l,e[i].r+1,e[i].f,(j+MAX_SIZE)%2);
      i++;
    }
    b=max(0,j);
    i--;
  }
  for(a=b;a<=n+m-2;a++){
      if(a<n) p=a;
      else p=2*(n-1)-a;
      if(a<m) q=a;
      else q=2*(m-1)-a;
      int l=max(0,n-p),r=min(n+m-1,n+q);
      //cout << a << ":" << l << ":" << r << ":" << getMin(l,r+1,a%2) << endl;
      if(getMin(l,r+1,a%2)==0) return true;
    }
  return false;
}
int main(){
  int i,j,x,y;
  cin>>n>>m>>k;
  for(i=0;i<k;i++){
    cin >> x >> y;
    v.push_back(P(x,y));
  }
  
  int l=0,r=n+m-2,mid;
  while(l+1<r){
    mid=(l+r)/2;
    //ccout << endl << l << ":" << r << ":" << mid << endl;
    if(check(mid)) l=mid;
    else r=mid;
  }
  if(k%n==0&&k/n==m) cout << 0 << endl;
  else cout << l+1 << endl;
  return 0;
}
accuracy: 1
time_ms: 2500
memory_kb: 16096
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
typedef pair<int,int> P;
typedef pair<P,int> PP;
int h,w,n,N=1<<17;
P a[100000];

class StarrySkyTree{
public:
  int Mi[333333],A[333333];
  void init(){fill(Mi,Mi+333333,0);fill(A,A+333333,0);}
  void add(int a,int b,int x,int k=0,int l=0,int r=N) {
    if(r<=a||b<=l) return;
    if(a<=l&&r<=b){
      A[k]+=x;
      while(k){
        k=(k-1)/2;
        Mi[k]=min(Mi[k*2+1]+A[k*2+1],Mi[k*2+2]+A[k*2+2]);
      }
      return;
    }
    add(a,b,x,k*2+1,l,(l+r)/2);
    add(a,b,x,k*2+2,(l+r)/2,r);
  }
  int getMin(int a,int b,int k=0,int l=0,int r=N) {
    if(r<=a||b<=l)return 1<<29;
    if(a<=l&&r<=b)return Mi[k]+A[k];
    int left=getMin(a,b,k*2+1,l,(l+r)/2),right=getMin(a,b,k*2+2,(l+r)/2,r);
    return min(left,right)+A[k];
  }
};

StarrySkyTree t[2];
vector<PP> v[2][111111];
bool calc(int m) {
  t[0].init(),t[1].init();
  for(int i=0; i<h+w+2; i++) v[0][i].clear(),v[1][i].clear();
  for(int i=0; i<n; i++) {
    int o=(a[i].F+a[i].S)%2;
    int d1=a[i].F+a[i].S-m;
    int d2=a[i].F+a[i].S+m;
    int x=w-(a[i].S-a[i].F+o)/2-1,y=abs(d1)%2;
    d1=max(0,d1),d2=min(h+w,d2);
    x-=(m+y)/2;
    v[0][d1].push_back(PP(P(max(0,x+y),min(h+w,x+m+1)),1));
    v[0][d2+1].push_back(PP(P(max(0,x+y),min(h+w,x+m+1)),-1));
    v[1][d1].push_back(PP(P(max(0,x),min(h+w,x+m+y)),1));
    v[1][d2+1].push_back(PP(P(max(0,x),min(h+w,x+m+y)),-1));
  }
  int z=1,l=w-1,r=w;
  bool f=0,f2=0;
  for(int i=0; i<h+w; i++) {
    for(int k=0; k<2; k++) {
      for(int j=0; j<v[k][i].size(); j++) t[k].add(v[k][i][j].F.F,v[k][i][j].F.S,v[k][i][j].S);
    }
    z=min(z,t[i%2].getMin(l,r));
    if(i>=w-1) f=1;
    if(i>=h-1) f2=1;
    l+=f?(i%2?1:0):(i%2?0:-1);
    r+=f2?(i%2?0:-1):(i%2?1:0);
  }
  return z;
}

int main() {
  cin >> h >> w >> n;
  for(int i=0; i<n; i++) cin >> a[i].F >> a[i].S;
  int l=-1,r=h+w;
  while(l+1<r) {
    int m=(l+r)/2;
    if(calc(m)) r=m;
    else l=m;
  }
  cout << r << endl;
  return 0;
}
accuracy: 1
time_ms: 2820
memory_kb: 32148
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#define N (1<<18)
#define INF (1e9)
using namespace std;
struct po{
  int l,r,x;
  po(){};
  po(int l,int r,int x):l(l),r(r),x(x){}
};
const int base=1e5+2;
int segMin[2][2*N-1], segAdd[2][2*N-1];
int w,h,m,x[N],y[N];
vector <po> mp[2][N];
po LR[N];

//starry sky tree
void add(int a,int b,int x,int k,int l,int r,int idx){
  if(r<=a||b<=l) return;
  if(a<=l&&r<=b){segAdd[idx][k]+=x;return;} 
  add(a,b,x,2*k+1,l,(l+r)/2,idx);
  add(a,b,x,2*k+2,(l+r)/2,r,idx);
  int L=segMin[idx][2*k+1]+segAdd[idx][2*k+1];
  int R=segMin[idx][2*k+2]+segAdd[idx][2*k+2];
  segMin[idx][k]=min(L,R);
}

int getMin(int a,int b,int k,int l,int r,int idx){
  if (r<=a||b<=l) return INF;
  if (a<=l&&r<=b) return segMin[idx][k]+segAdd[idx][k];
  int L=getMin(a,b,2*k+1,l,(l+r)/2,idx);
  int R=getMin(a,b,2*k+2,(l+r)/2,r,idx);
  return min(L,R)+segAdd[idx][k];
}

void mk_LR(){
  for(int i=0;i<h&&w==1;i++)LR[base+i]=po(base,base,i%2);
  if(w==1)return;

  LR[base]=po(base,base,0),LR[base+1]=po(base,base+1,1);
  int mn=min(w,h),S,cnt=0;
  for(int i=1;i<mn;i++) cnt+=2*i;
  S=(w*h-cnt)/mn;
  if(w==2)S--;
  for(int i=base+2;;i++){
    int l=LR[i-2].l-1,r=LR[i-2].r+1,x=LR[i-2].x;

    if(S==0&&!x)l=LR[i-1].l,r=l+mn-2,S--;
    else if(S==0&&x)l=LR[i-1].l+1,r=LR[i-1].r,S--;
    else if(S<0) l+=2,r-=2;
    if(l>r)break;
    if(r-l+1>mn) l=LR[i-2].l,r=l+mn-1;
    if(S>0&&LR[i-2].r-LR[i-2].l+1==mn)l=LR[i-2].l+1,r=l+mn-1;
    if(r-l+1==mn)S--;
    LR[i]=po(l,r,x);
  }
}

void mk_mp(int d){
  for(int i=0;i<N;i++) mp[0][i].clear(),mp[1][i].clear();
  
  for(int i=0;i<m;i++){
    int idx=y[i]+(w-x[i]-1)+base;
    int c=LR[idx].l+min(y[i],x[i]);
    int a=idx%2,l=c-d/2,r=c+d/2;
    if(d%2==0){
      mp[a][idx-d].push_back(po(l,r,1));
      mp[a][idx+d+1].push_back(po(l,r,-1));

      mp[!a][idx-d+1].push_back(po(l+!a,r-a,1));
      mp[!a][idx+d].push_back(po(l+!a,r-a,-1));
    }
    else {
      mp[!a][idx-d].push_back(po(l-a,r+!a,1));
      mp[!a][idx+d+1].push_back(po(l-a,r+!a,-1));
      
      mp[a][idx-d+1].push_back(po(l,r,1));
      mp[a][idx+d].push_back(po(l,r,-1));
    }
  }
}


bool check(int d){
  mk_mp(d);
  memset(segMin,0,sizeof(segMin));
  memset(segAdd,0,sizeof(segAdd));
  for(int i=0;i<N;i++){

    for(int k=0;k<2;k++)
      for(int j=0;j<mp[k][i].size();j++)
	add(mp[k][i][j].l,mp[k][i][j].r+1,mp[k][i][j].x,0,0,N,k);
    
    if(LR[i].l&&!getMin(LR[i].l,LR[i].r+1,0,0,N,i%2))return 1;
  }
  return 0; 
}

int search(){
  int L=0,M,R=100001;
  while(L<R){
    M=(L+R)/2;
    if(!check(M)) R=M;
    else L=M+1;
  }
  return L;
}

int main(){
  cin>>w>>h>>m;
  for(int i=0;i<m;i++)cin>>x[i]>>y[i];
  if(w>h){
    swap(w,h);
    for(int i=0;i<m;i++)swap(x[i],y[i]); 
  }
  mk_LR();
 
  cout <<search()<<endl;
  return 0;
}
accuracy: 1
time_ms: 2830
memory_kb: 72148
final_rank: 8

code_snippet: #include <bits/stdc++.h>
#define N (1<<18)
#define INF (1e9)
using namespace std;
struct po{
  int l,r,x;
  po(){};
  po(int l,int r,int x):l(l),r(r),x(x){}
};
const int base=1e5+2;
int segMin[2][2*N-1], segAdd[2][2*N-1];
int w,h,m,x[N],y[N];
vector <po> mp[2][N];
po LR[N];

//starry sky tree
void add(int a,int b,int x,int k,int l,int r,int idx){
  if(r<=a||b<=l) return;
  if(a<=l&&r<=b){segAdd[idx][k]+=x;return;} 
  add(a,b,x,2*k+1,l,(l+r)/2,idx);
  add(a,b,x,2*k+2,(l+r)/2,r,idx);
  int L=segMin[idx][2*k+1]+segAdd[idx][2*k+1];
  int R=segMin[idx][2*k+2]+segAdd[idx][2*k+2];
  segMin[idx][k]=min(L,R);
}

int getMin(int a,int b,int k,int l,int r,int idx){
  if (r<=a||b<=l) return INF;
  if (a<=l&&r<=b) return segMin[idx][k]+segAdd[idx][k];
  int L=getMin(a,b,2*k+1,l,(l+r)/2,idx);
  int R=getMin(a,b,2*k+2,(l+r)/2,r,idx);
  return min(L,R)+segAdd[idx][k];
}

void mk_LR(){
  
  for(int i=0;i<h&&w==1;i++)LR[i+base]=po(base+i,base+i,i%2);
  if(w==1)return;
  LR[base]=po(base,base,0);
  LR[base+1]=po(base,base+1,1);
  int mn=min(w,h),S,cnt=0;
  for(int i=1;i<mn;i++) cnt+=2*i;
  S=(w*h-cnt)/mn;
  if(w==2)S--;
  for(int i=base+2;;i++){
    int l=LR[i-2].l-1,r=LR[i-2].r+1,x=LR[i-2].x;

    if(S==0&&!x)l=LR[i-1].l,r=l+mn-2,S--;
    else if(S==0&&x)l=LR[i-1].l+1,r=LR[i-1].r,S--;
    else if(S<0) l+=2,r-=2;
    if(l>r)break;
    if(r-l+1>mn) l=LR[i-2].l,r=l+mn-1;
    if(S>0&&LR[i-2].r-LR[i-2].l+1==mn)l=LR[i-2].l+1,r=l+mn-1;
    if(r-l+1==mn)S--;
    LR[i]=po(l,r,x);
  }
}

void mk_mp(int d){
  for(int i=0;i<N;i++) mp[0][i].clear();
  for(int i=0;i<N;i++) mp[1][i].clear();
  
  for(int i=0;i<m;i++){
    int idx=y[i]+(w-x[i]-1)+base;
    int c=LR[idx].l+min(y[i],x[i]);
    int a=idx%2,b=(idx+d)%2;
    int D=d/2;
    if(d%2==0){
      mp[b][idx-d].push_back(po(c-D,c+D,1));
      mp[b][idx+d+1].push_back(po(c-D,c+D,-1));

      mp[!b][idx-d+1].push_back(po(c-D+!a,c+D-a,1));
      mp[!b][idx+d].push_back(po(c-D+!a,c+D-a,-1));
    }
    else {
      mp[b][idx-d].push_back(po(c-D-a,c+D+!a,1));
      mp[b][idx+d+1].push_back(po(c-D-a,c+D+!a,-1));
      
      mp[!b][idx-d+1].push_back(po(c-D,c+D,1));
      mp[!b][idx+d].push_back(po(c-D,c+D,-1));
    }
  }
}


bool check(int d){
  mk_mp(d);
  memset(segMin,0,sizeof(segMin));
  memset(segAdd,0,sizeof(segAdd));
  for(int i=0;i<N;i++){
    int bit=i%2;
    for(int k=0;k<2;k++)
      for(int j=0;j<(int)mp[k][i].size();j++)add(mp[k][i][j].l,mp[k][i][j].r+1,mp[k][i][j].x,0,0,N,k);


    if(LR[i].l&&!getMin(LR[i].l,LR[i].r+1,0,0,N,bit))return 1;
  }
  return 0; 
}

int search(){
  if(w==1){
    sort(y,y+m);
    int res=max(y[0],h-y[m-1]-1);    
    for(int i=1;i<m;i++) res=max(res,(y[i]-y[i-1]-1)/2+(y[i]-y[i-1]-1)%2);
    return res;
  }
 
  int L=0,M,R=100001;
  while(L<R){
    M=(L+R)/2;
    if(!check(M)) R=M;
    else L=M+1;
  }
  return L;
}
int main(){
  cin>>w>>h>>m;
  for(int i=0;i<m;i++)cin>>x[i]>>y[i];
  if(w>h){
    swap(w,h);
    for(int i=0;i<m;i++)swap(x[i],y[i]); 
  }
  mk_LR();
  cout <<search()<<endl;
  return 0;
}
accuracy: 1
time_ms: 2820
memory_kb: 72152
final_rank: 7

code_snippet: #include <bits/stdc++.h>
#define N (1<<18)
#define INF (1e9)
using namespace std;
struct po{
  int l,r,x;
  po(){};
  po(int l,int r,int x):l(l),r(r),x(x){}
};
const int base=1e5+2;
int segMin[2][2*N-1], segAdd[2][2*N-1];
int w,h,m,x[N],y[N];
vector <po> mp[2][N];
po LR[N];

//starry sky tree
void add(int a,int b,int x,int k,int l,int r,int idx){
  if(r<=a||b<=l) return;
  if(a<=l&&r<=b){segAdd[idx][k]+=x;return;} 
  add(a,b,x,2*k+1,l,(l+r)/2,idx);
  add(a,b,x,2*k+2,(l+r)/2,r,idx);
  int L=segMin[idx][2*k+1]+segAdd[idx][2*k+1];
  int R=segMin[idx][2*k+2]+segAdd[idx][2*k+2];
  segMin[idx][k]=min(L,R);
}

int getMin(int a,int b,int k,int l,int r,int idx){
  if (r<=a||b<=l) return INF;
  if (a<=l&&r<=b) return segMin[idx][k]+segAdd[idx][k];
  int L=getMin(a,b,2*k+1,l,(l+r)/2,idx);
  int R=getMin(a,b,2*k+2,(l+r)/2,r,idx);
  return min(L,R)+segAdd[idx][k];
}

void mk_LR(){
  
  for(int i=0;i<h&&w==1;i++)LR[i+base]=po(base+i,base+i,i%2);
  if(w==1)return;
  LR[base]=po(base,base,0);
  LR[base+1]=po(base,base+1,1);
  int mn=min(w,h),S,cnt=0;
  for(int i=1;i<mn;i++) cnt+=2*i;
  S=(w*h-cnt)/mn;
  if(w==2)S--;
  for(int i=base+2;;i++){
    int l=LR[i-2].l-1,r=LR[i-2].r+1,x=LR[i-2].x;

    if(S==0&&!x)l=LR[i-1].l,r=l+mn-2,S--;
    else if(S==0&&x)l=LR[i-1].l+1,r=LR[i-1].r,S--;
    else if(S<0) l+=2,r-=2;
    if(l>r)break;
    if(r-l+1>mn) l=LR[i-2].l,r=l+mn-1;
    if(S>0&&LR[i-2].r-LR[i-2].l+1==mn)l=LR[i-2].l+1,r=l+mn-1;
    if(r-l+1==mn)S--;
    LR[i]=po(l,r,x);
  }
}

void mk_mp(int d){
  for(int i=0;i<N;i++) mp[0][i].clear();
  for(int i=0;i<N;i++) mp[1][i].clear();
  
  for(int i=0;i<m;i++){
    int idx=y[i]+(w-x[i]-1)+base;
    int c=LR[idx].l+min(y[i],x[i]);
    int a=idx%2,b=(idx+d)%2;
    int D=d/2;
    if(d%2==0){
      mp[b][idx-d].push_back(po(c-D,c+D,1));
      mp[b][idx+d+1].push_back(po(c-D,c+D,-1));

      mp[!b][idx-d+1].push_back(po(c-D+!a,c+D-a,1));
      mp[!b][idx+d].push_back(po(c-D+!a,c+D-a,-1));
    }
    else {
      mp[b][idx-d].push_back(po(c-D-a,c+D+!a,1));
      mp[b][idx+d+1].push_back(po(c-D-a,c+D+!a,-1));
      
      mp[!b][idx-d+1].push_back(po(c-D,c+D,1));
      mp[!b][idx+d].push_back(po(c-D,c+D,-1));
    }
  }
}


bool check(int d){
  mk_mp(d);
   for(int i=0;i<N;i++){
    int bit=i%2;
    for(int k=0;k<2;k++)
      for(int j=0;j<(int)mp[k][i].size();j++)add(mp[k][i][j].l,mp[k][i][j].r+1,mp[k][i][j].x,0,0,N,k);

    if(LR[i].l&&!getMin(LR[i].l,LR[i].r+1,0,0,N,bit))return 1;
  }
  return 0; 
}

int search(){
  if(w==1){
    sort(y,y+m);
    int res=max(y[0],h-y[m-1]-1);    
    for(int i=1;i<m;i++) res=max(res,(y[i]-y[i-1]-1)/2+(y[i]-y[i-1]-1)%2);
    return res;
  }
 
  int L=0,M,R=100001;
  while(L<R){
    M=(L+R)/2;
    if(!check(M)) R=M;
    else L=M+1;
  }
  return L;
}
int main(){
  cin>>w>>h>>m;
  for(int i=0;i<m;i++)cin>>x[i]>>y[i];
  if(w>h){
    swap(w,h);
    for(int i=0;i<m;i++)swap(x[i],y[i]); 
  }
  mk_LR();
  cout <<search()<<endl;
  return 0;
}
accuracy: 0.04
time_ms: 40
memory_kb: 16016
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#define N (1<<18)
#define INF (1e9)
using namespace std;
struct po{
  int l,r,x;
  po(){};
  po(int l,int r,int x):l(l),r(r),x(x){}
};
const int base=1e5+2;
int segMin[2][2*N-1], segAdd[2][2*N-1];
int w,h,m,x[N],y[N];
vector <po> mp[2][N];
po LR[N];

//starry sky tree
void add(int a,int b,int x,int k,int l,int r,int idx){
  if(r<=a||b<=l) return;
  if(a<=l&&r<=b){segAdd[idx][k]+=x;return;} 
  add(a,b,x,2*k+1,l,(l+r)/2,idx);
  add(a,b,x,2*k+2,(l+r)/2,r,idx);
  int L=segMin[idx][2*k+1]+segAdd[idx][2*k+1];
  int R=segMin[idx][2*k+2]+segAdd[idx][2*k+2];
  segMin[idx][k]=min(L,R);
}

int getMin(int a,int b,int k,int l,int r,int idx){
  if (r<=a||b<=l) return INF;
  if (a<=l&&r<=b) return segMin[idx][k]+segAdd[idx][k];
  int L=getMin(a,b,2*k+1,l,(l+r)/2,idx);
  int R=getMin(a,b,2*k+2,(l+r)/2,r,idx);
  return min(L,R)+segAdd[idx][k];
}

void mk_LR(){
  memset(LR,0,sizeof(LR));

  for(int i=0;i<h&&w==1;i++)LR[i+base]=po(base+i,base+i,i%2);
  if(w==1)return;
  LR[base]=po(base,base,0);
  LR[base+1]=po(base,base+1,1);
  int mn=min(w,h),S,cnt=0;
  for(int i=1;i<mn;i++) cnt+=2*i;
  S=(w*h-cnt)/mn;
  if(w==2)S--;
  for(int i=base+2;;i++){
    int l=LR[i-2].l-1,r=LR[i-2].r+1,x=LR[i-2].x;

    if(S==0&&!x)l=LR[i-1].l,r=l+mn-2,S--;
    else if(S==0&&x)l=LR[i-1].l+1,r=LR[i-1].r,S--;
    else if(S<0) l+=2,r-=2;
    if(l>r)break;
    if(r-l+1>mn) l=LR[i-2].l,r=l+mn-1;
    if(S>0&&LR[i-2].r-LR[i-2].l+1==mn)l=LR[i-2].l+1,r=l+mn-1;
    if(r-l+1==mn)S--;
    LR[i]=po(l,r,x);
  }
  
  /*
  for(int i=0;i<N;i++){
    if(LR[i].l==0)continue;
    cout <<i-base<<" "<<LR[i].l-base<<" "<<LR[i].r-base<<endl;
    }
  */
}

void mk_mp(int d){
  for(int i=0;i<N;i++) mp[0][i].clear();
  for(int i=0;i<N;i++) mp[1][i].clear();
  
  for(int i=0;i<m;i++){
    int idx=y[i]+(w-x[i]-1)+base;
    int c=LR[idx].l+min(y[i],x[i]);
    int a=idx%2,b=(idx+d)%2;
    int D=d/2;
    //    cout <<idx-base<<" "<<c-base<<endl;
    //cout <<"a="<<a<<endl;
    if(d%2==0){
      mp[b][idx-d].push_back(po(c-D,c+D,1));
      mp[b][idx+d+1].push_back(po(c-D,c+D,-1));

      mp[!b][idx-d+1].push_back(po(c-D+!a,c+D-a,1));
      mp[!b][idx+d].push_back(po(c-D+!a,c+D-a,-1));
    }
    else {
      mp[b][idx-d].push_back(po(c-D-a,c+D+!a,1));
      mp[b][idx+d+1].push_back(po(c-D-a,c+D+!a,-1));
      
      mp[!b][idx-d+1].push_back(po(c-D,c+D,1));
      mp[!b][idx+d].push_back(po(c-D,c+D,-1));
    }
  }
  /*
    for(int i=0;i<N;i++)
    for(int j=0;j<2;j++)
    if(mp[j][i].size())
    cout <<"j="<<j<<" "<<i-base<<" "<<mp[j][i][0].l-base<<" "<<mp[j][i][0].r-base<<" "<<mp[j][i][0].x<<endl;
  */
}


bool check(int d){
  mk_mp(d);
  memset(segMin,0,sizeof(segMin));
  memset(segAdd,0,sizeof(segAdd));
  for(int i=0;i<N;i++){
    int bit=i%2;
    for(int k=0;k<2;k++)
      for(int j=0;j<(int)mp[k][i].size();j++)add(mp[k][i][j].l,mp[k][i][j].r+1,mp[k][i][j].x,0,0,N,k);
    if(LR[i].l&&!getMin(LR[i].l,LR[i].r+1,0,0,N,bit))return 1;
  }
  return 0; 
}

int search(){
  if(w==1){
    sort(y,y+m);
    int res=max(y[0],h-y[m-1]-1);    
    for(int i=1;i<m;i++) res=max(res,(y[i]-y[i-1]-1)/2+(y[i]-y[i-1]-1)%2);
    return res;
  }
 
  int L=0,M,R=100001;
  while(L<R){
    M=(L+R)/2;
    if(!check(M)) R=M;
    else L=M+1;
  }
  return L;
}

void debug(){
  int MP[100][100]={};
  cout <<"P2"<<endl;
  cout <<100<<" "<<100<<endl;
  cout <<15<<endl;
  for(int i=0;i<N;i++)
    if(LR[i].l)
      for(int j=LR[i].l;j<LR[i].r+1;j++) MP[i-base+50][j-base+50]=j%2? 10:15;

  /*  mk_mp(11);
      for(int i=0;i<N;i++)
      for(int j=0;j<mp[i].size();j++)
      for(int k=mp[i][j].l;k<mp[i][j].r+1;k++)MP[i-base+50-(mp[i][j].x==-1)][k-base+50]=5;
  */  

  
  for(int i=99;i>=0;i--){
    for(int j=0;j<100;j++){
      if(j)cout <<" ";
      cout <<MP[i][j];
    }
    cout <<endl;
  }
}

int main(){
  cin>>w>>h>>m;
  for(int i=0;i<m;i++)cin>>x[i]>>y[i];
  if(w>h){
    swap(w,h);
    for(int i=0;i<m;i++)swap(x[i],y[i]); 
  }
  mk_LR();
  //cout<<check(2)<<endl;
  //debug();
  cout <<search()<<endl;
  return 0;
}
accuracy: 1
time_ms: 2850
memory_kb: 74176
final_rank: 9

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

typedef int _loop_int;
#define REP(i,n) for(_loop_int i=0;i<(_loop_int)(n);++i)
#define FOR(i,a,b) for(_loop_int i=(_loop_int)(a);i<(_loop_int)(b);++i)
#define FORR(i,a,b) for(_loop_int i=(_loop_int)(b)-1;i>=(_loop_int)(a);--i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(__i,v.size())cout<<" "<<v[__i];cout<<endl
#define ALL(a) (a).begin(),(a).end()

#define CHMIN(a,b) a=min((a),(b))
#define CHMAX(a,b) a=max((a),(b))

// mod
const ll MOD = 1000000007ll;
#define FIX(a) ((a)%MOD+MOD)%MOD

// floating
typedef double Real;
const Real EPS = 1e-11;
#define EQ0(x) (abs(x)<EPS)
#define EQ(a,b) (abs(a-b)<EPS)
typedef complex<Real> P;

int n,m,k;
pii rob[125252];
const int INF = 830252521;

const int S_MAX = 1<<17;
// seg tree
struct segtree{
  vi dat,sum;
  segtree(){
    init();
  }
  void init(){
    dat.assign(S_MAX*2-1,0);
    sum.assign(S_MAX*2-1,0);
  }
  void add(int l,int r,int v,int a,int b,int k){
    if(r<=a || b<=l)return;
    if(l<=a && b<=r){
      sum[k] += v;
      dat[k] += v;
    }else{
      int m = (a+b)/2;
      add(l,r,v,a,m,2*k+1);
      add(l,r,v,m,b,2*k+2);
      dat[k] = sum[k] + min(dat[2*k+1],dat[2*k+2]);
    }
  }
  void add(int l,int r,int v){
    add(l,r,v,0,S_MAX,0);
  }
  int segmin(int l,int r,int a,int b,int k){
    if(r<=a || b<=l)return INF;
    if(l<=a && b<=r){
      return dat[k];
    }else{
      int m = (a+b)/2;
      return sum[k] + min(segmin(l,r,a,m,2*k+1),segmin(l,r,m,b,2*k+2));
    }
  }
  int segmin(int l,int r){
    return segmin(l,r,0,S_MAX,0);
  }
};

const int C = S_MAX>>1;
bool check(int w){
  // init
  segtree X,Y;
  X.init();
  Y.init();

  int head = 0, tail = 0;
  REP(i,n+m+1){
    // seek and add
    while(head < k){
      if(rob[head].first-w <= i){
        // add
        int x = rob[head].first;
        int y = rob[head].second;
        if((x-w)%2==0){
          X.add((S_MAX+y-w)/2,  (S_MAX+y+w)/2+1,  1);
          Y.add((S_MAX+y-w+1)/2,(S_MAX+y+w-1)/2+1,1);
        }else{
          Y.add((S_MAX+y-w)/2,  (S_MAX+y+w)/2+1,  1);
          X.add((S_MAX+y-w+1)/2,(S_MAX+y+w-1)/2+1,1);
        }
        head++;
      }else{
        break;
      }
    }
    // check
    int up = i<=(n-1) ? i : 2*(n-1)-i;
    int ud = i<=(m-1) ? -i : i-2*(m-1);

    // debug
    // DEBUG(i);
    // printf("%*s 0\n",2*C,"");
    // REP(j,S_MAX)printf("%2d",X.segmin(j,j+1));putchar('\n');
    // REP(j,S_MAX)printf("%2d",Y.segmin(j,j+1));putchar('\n');
    // DEBUG(ud);
    // DEBUG(up);
    // if(i%2==0){
    //   DEBUG(ud/2);
    //   DEBUG(up/2);
    // }else{
    //   DEBUG((ud-1)/2);
    //   DEBUG((up-1)/2);
    // }
    if(i%2==0){
      if(X.segmin((S_MAX+ud)/2,(S_MAX+up)/2+1)==0){
        return false;
      }
    }else{
      if(Y.segmin((S_MAX+ud-1)/2,(S_MAX+up-1)/2+1)==0){
        return false;
      }
    }
    // seek and remove
    while(tail < k){
      if(rob[tail].first+w <= i){
        // add
        int x = rob[tail].first;
        int y = rob[tail].second;
        if((x-w)%2==0){
          X.add((S_MAX+y-w)/2,  (S_MAX+y+w)/2+1,  -1);
          Y.add((S_MAX+y-w+1)/2,(S_MAX+y+w-1)/2+1,-1);
        }else{
          Y.add((S_MAX+y-w)/2,  (S_MAX+y+w)/2+1,  -1);
          X.add((S_MAX+y-w+1)/2,(S_MAX+y+w-1)/2+1,-1);
        }
        tail++;
      }else{
        break;
      }
    }
  }
  return true;
}

int main(){
  scanf("%d%d%d",&n,&m,&k);
  REP(i,k){
    int x,y;
    scanf("%d%d",&x,&y);
    rob[i] = pii(x+y,x-y);
  }
  sort(rob,rob+k);
  int low = -1, high = n+m+2;
  // DEBUG(check(14));
  while(low+1<high){
    int mid = (low+high)/2;
    if(check(mid)){
      high = mid;
    }else{
      low = mid;
    }
  }
  printf("%d\n",high);
  return 0;
}
accuracy: 1
time_ms: 1550
memory_kb: 6200
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define int long long
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;
#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,f,n) for(int i=(f);i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define pb push_back
#define fi first
#define se second
template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

struct segtree{
    static const int SEG=1<<20;
    vint dat,put;
    segtree():dat(SEG*2),put(SEG*2){}
    inline void push(int k){
        dat[k]+=put[k];
        if(k<SEG-1){
            put[k*2+1]+=put[k];
            put[k*2+2]+=put[k];
        }
        put[k]=0;
    }
    void add(int a,int b,int x=0,int k=0,int l=0,int r=SEG){
        push(k);
        if(r<=a||b<=l)return;
        if(a<=l&&r<=b){
            put[k]+=x;
            push(k);
            return;
        }
        add(a,b,x,k*2+1,l,(l+r)/2);
        add(a,b,x,k*2+2,(l+r)/2,r);
        dat[k]=min(dat[k*2+1],dat[k*2+2]);
    }
    int query(int a,int b,int k=0,int l=0,int r=SEG){
        push(k);
        if(r<=a||b<=l)return 1001001001;
        if(a<=l&&r<=b)return dat[k];
        return min(query(a,b,k*2+1,l,(l+r)/2),query(a,b,k*2+2,(l+r)/2,r));
    }
};

int H,W,K;
int X[100000],Y[100000];

vector<tuple<int,int,int>>es[100000];

int base=300000;
bool C(int L){
    rep(i,100000)es[i].clear();
    rep(i,K){
        int lx=X[i]-L;
        int rx=X[i]+L+1;
        chmax(lx,0ll);
        chmin(rx,100000ll);
        es[lx].pb(make_tuple(Y[i]-L,Y[i]+L+1,1));
        es[rx].pb(make_tuple(Y[i]-L,Y[i]+L+1,-1));
    }

    segtree seg;

    int ly=1,ry=0;
    for(int x=0;x<H+W-1;x++){
        for(int i=0;i<es[x].size();i++){
            int a,b,k;
            tie(a,b,k)=es[x][i];
            seg.add(a+base,b+base,k);
        }
        if(x<H){
            ly--;ry++;
        }
        else if(x<W){
            ly--;ry--;
        }
        else{
            ly++;ry--;
        }
        if(seg.query(ly+base,ry+base)==0)return false;
    }
    return true;
}

signed main(){
    cin>>W>>H>>K;
    rep(i,K)cin>>X[i]>>Y[i];

    if(W<H){
        swap(W,H);
        rep(i,K)swap(X[i],Y[i]);
    }
    rep(i,K){
        int x=X[i]+Y[i];
        int y=-X[i]+Y[i];
        X[i]=x;Y[i]=y;
    }

    int lb=-1,ub=100010;
    while(ub-lb>1){
        int mid=(ub+lb)/2;
        if(C(mid))ub=mid;
        else lb=mid;
    }
    cout<<ub<<endl;
    return 0;
}
accuracy: 0.16
time_ms: 120
memory_kb: 38052
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define int long long
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;
#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,f,n) for(int i=(f);i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define pb push_back
#define fi first
#define se second
template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

struct segtree{
    static const int SEG=1<<20;
    vint dat,put;
    segtree():dat(SEG*2),put(SEG*2){}
    inline void push(int k){
        dat[k]+=put[k];
        if(k<SEG-1){
            put[k*2+1]+=put[k];
            put[k*2+2]+=put[k];
        }
        put[k]=0;
    }
    void add(int a,int b,int x=0,int k=0,int l=0,int r=SEG){
        push(k);
        if(r<=a||b<=l)return;
        if(a<=l&&r<=b){
            put[k]+=x;
            push(k);
            return;
        }
        add(a,b,x,k*2+1,l,(l+r)/2);
        add(a,b,x,k*2+2,(l+r)/2,r);
        dat[k]=min(dat[k*2+1],dat[k*2+2]);
    }
    int query(int a,int b,int k=0,int l=0,int r=SEG){
        push(k);
        if(r<=a||b<=l)return 1001001001;
        if(a<=l&&r<=b)return dat[k];
        return min(query(a,b,k*2+1,l,(l+r)/2),query(a,b,k*2+2,(l+r)/2,r));
    }
};

int H,W,K;
int X[100000],Y[100000];

vector<tuple<int,int,int>>es[100000];

int base=300000;
bool C(int L){
    rep(i,100000)es[i].clear();
    rep(i,K){
        int lx=X[i]-L;
        int rx=X[i]+L+1;
        chmax(lx,0ll);
        chmin(rx,100000ll);
        es[lx].pb(make_tuple(Y[i]-L,Y[i]+L+1,1));
        es[rx].pb(make_tuple(Y[i]-L,Y[i]+L+1,-1));
    }

    segtree seg;

    int ly=1,ry=0;
    for(int x=0;x<H+W-1;x++){
        for(int i=0;i<es[x].size();i++){
            int a,b,k;
            tie(a,b,k)=es[x][i];
            seg.add(a+base,b+base,k);
        }
        if(x<H){
            ly--;ry++;
        }
        else if(x<W){
            ly--;ry--;
        }
        else{
            ly++;ry--;
        }
        if(seg.query(ly+base,ry+base)==0)return false;
    }
    return true;
}

signed main(){
    cin>>W>>H>>K;
    rep(i,K)cin>>X[i]>>Y[i];

    if(W<H){
        swap(W,H);
        rep(i,K)swap(X[i],Y[i]);
    }
    rep(i,K){
        int x=X[i]+Y[i];
        int y=-X[i]+Y[i];
        X[i]=x;Y[i]=y;
    }

    int lb=-1,ub=100000;
    while(ub-lb>1){
        int mid=(ub+lb)/2;
        if(C(mid))ub=mid;
        else lb=mid;
    }
    cout<<ub<<endl;
    return 0;
}
accuracy: 0.16
time_ms: 120
memory_kb: 38052
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define int long long
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;
#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,f,n) for(int i=(f);i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define pb push_back
#define fi first
#define se second
template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

struct segtree{
    static const int SEG=1<<20;
    vint dat,put;
    segtree():dat(SEG*2),put(SEG*2){}
    inline void push(int k){
        dat[k]+=put[k];
        if(k<SEG-1){
            put[k*2+1]+=put[k];
            put[k*2+2]+=put[k];
        }
        put[k]=0;
    }
    void add(int a,int b,int x=0,int k=0,int l=0,int r=SEG){
        push(k);
        if(r<=a||b<=l)return;
        if(a<=l&&r<=b){
            put[k]+=x;
            push(k);
            return;
        }
        add(a,b,x,k*2+1,l,(l+r)/2);
        add(a,b,x,k*2+2,(l+r)/2,r);
        dat[k]=min(dat[k*2+1],dat[k*2+2]);
    }
    int query(int a,int b,int k=0,int l=0,int r=SEG){
        push(k);
        if(r<=a||b<=l)return 1001001001;
        if(a<=l&&r<=b)return dat[k];
        return min(query(a,b,k*2+1,l,(l+r)/2),query(a,b,k*2+2,(l+r)/2,r));
    }
};

int H,W,K;
int X[50000],Y[50000];

vector<tuple<int,int,int>>es[100000];

int base=300000;
bool C(int L){
    rep(i,100000)es[i].clear();
    rep(i,K){
        int lx=X[i]-L;
        int rx=X[i]+L+1;
        chmax(lx,0ll);
        chmin(rx,100000ll);
        es[lx].pb(make_tuple(Y[i]-L,Y[i]+L+1,1));
        es[rx].pb(make_tuple(Y[i]-L,Y[i]+L+1,-1));
    }

    segtree seg;

    int ly=1,ry=0;
    for(int x=0;x<H+W-1;x++){
        for(int i=0;i<es[x].size();i++){
            int a,b,k;
            tie(a,b,k)=es[x][i];
            seg.add(a+base,b+base,k);
        }
        if(x<H){
            ly--;ry++;
        }
        else if(x<W){
            ly--;ry--;
        }
        else{
            ly++;ry--;
        }
        if(seg.query(ly+base,ry+base)==0)return false;
    }
    return true;
}

signed main(){
    cin>>W>>H>>K;
    rep(i,K)cin>>X[i]>>Y[i];

    if(W<H){
        swap(W,H);
        rep(i,K)swap(X[i],Y[i]);
    }
    rep(i,K){
        int x=X[i]+Y[i];
        int y=-X[i]+Y[i];
        X[i]=x;Y[i]=y;
    }

    int lb=-1,ub=100000;
    while(ub-lb>1){
        int mid=(ub+lb)/2;
        if(C(mid))ub=mid;
        else lb=mid;
    }
    cout<<ub<<endl;
    return 0;
}
accuracy: 0.16
time_ms: 120
memory_kb: 38052
final_rank: 10

code_snippet: #include "bits/stdc++.h"
using namespace std;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))
#define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))
static const int INF = 0x3f3f3f3f; static const long long INFL = 0x3f3f3f3f3f3f3f3fLL;
typedef vector<int> vi; typedef pair<int, int> pii; typedef vector<pair<int, int> > vpii; typedef long long ll;
template<typename T, typename U> static void amin(T &x, U y) { if(y < x) x = y; }
template<typename T, typename U> static void amax(T &x, U y) { if(x < y) x = y; }

struct AddMaxSegmentTree {
	typedef int Val;
	typedef int Add;
	vector<Val> nodes;
	vector<Val> add;
	int n;
	void init(int minN) {
		n = 1; while(n < minN) n *= 2;
		nodes.assign(n * 2, Val());
		add.assign(n * 2, Val());
	}
	Val getRange(int i, int j) {
		if(i >= j) return -INF;
		return getRangeRec(1, i, j, 0, n);
	}
	void addToRange(int i, int j, Add a) {
		if(i < j) addToRangeRec(1, i, j, a, 0, n);
	}
	Val getRangeRec(int i, int qL, int qR, int L, int R) {
		Val a = add[i];
		if(qL <= L && R <= qR)
			return nodes[i] + a;
		if(a != 0) {
			add[i * 2] += a;
			add[i * 2 + 1] += a;
			nodes[i] += a;
			add[i] = 0;
		}
		int mid = (L + R) >> 1;
		Val r = -INF;
		if(qL < mid) amax(r, getRangeRec(i * 2 + 0, qL, qR, L, mid));
		if(mid < qR) amax(r, getRangeRec(i * 2 + 1, qL, qR, mid, R));
		nodes[i] = max(nodes[i * 2] + add[i * 2], nodes[i * 2 + 1] + add[i * 2 + 1]);
		return r;
	}
	void addToRangeRec(int i, int qL, int qR, Add a, int L, int R) {
		if(qL <= L && R <= qR) {
			add[i] += a;
			return;
		}
		int mid = (L + R) >> 1;
		if(qL < mid) addToRangeRec(i * 2 + 0, qL, qR, a, L, mid);
		if(mid < qR) addToRangeRec(i * 2 + 1, qL, qR, a, mid, R);
		nodes[i] = max(nodes[i * 2] + add[i * 2], nodes[i * 2 + 1] + add[i * 2 + 1]);
	}
};


struct Event {
	int L, R;
	int sign;
};
int main() {
	int n; int m; int k;
	while(~scanf("%d%d%d", &n, &m, &k)) {
		vpii ab(k);
		rep(i, k) {
			int y; int x;
			scanf("%d%d", &y, &x);
			ab[i] = { y + x, y - x };
		}
		vector<pair<int, int>> border(n + m - 1, make_pair(INF, -INF));
		auto setborder = [&border](int y, int x) {
			int a = y + x, b = y - x;
			amin(border[a].first, b);
			amax(border[a].second, b);
		};
		rep(y, n) {
			setborder(y, 0);
			setborder(y, m - 1);
		}
		rep(x, m) {
			setborder(0, x);
			setborder(n - 1, x);
		}
		int lo = -1, up = n + m - 1;
		while(up - lo > 0) {
			int mid = (lo + up + 1) / 2;
			vector<vector<Event>> events(n + m);
			for(auto p : ab) {
				int top = max(0, p.first - mid);
				int bot = min(n + m - 1, p.first + 1 + mid);
				int L = max(-m, p.second - mid);
				int R = min(+n, p.second + 1 + mid);
				events[top].push_back(Event{ L, R, +1 });
				events[bot].push_back(Event{ L, R, -1 });
			}
			AddMaxSegmentTree segt[2];
			rep(p, 2) segt[p].init(m + n + 1);
			auto convert = [](int &L, int &R, int p) {
				if((L & 1) != p) ++ L;
				if((R & 1) != p) ++ R;
				L = (L - p) / 2;
				R = (R - p) / 2;
			};
			bool ok = true;
			rep(a, n + m - 1) {
				for(auto e : events[a]) {
					rep(p, 2) {
						int L = e.L, R = e.R;
						convert(L, R, p);
						segt[p].addToRange(L + m, R + m, -e.sign);
					}
				}
				int L = border[a].first, R = border[a].second + 1;
				convert(L, R, a % 2);
				if(segt[a % 2].getRange(L + m, R + m) == 0) {
					ok = false;
					break;
				}
			}
			if(ok)
				up = mid - 1;
			else
				lo = mid;
		}
		printf("%d\n", lo + 1);
	}
	return 0;
}
accuracy: 1
time_ms: 1210
memory_kb: 14400
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<b;i++)
#define REP(i,b) FOR(i,0,b)
#define PB push_back

using ll=long long;
using pii=pair<int,int>;
using vi=vector<int>;

int read(){
	int i;
	scanf("%d",&i);
	return i;
}

const int inf=1000000007;
struct Seg{
	int mn[1<<18],lz[1<<18],s;
	void Init(int n){
		s=1;
		while(s<n)s*=2;
		fill(mn,mn+s*2,0);
		fill(lz,lz+s*2,0);
	}
	int NodeMin(int i){
		return mn[i]+lz[i];
	}
	void Propagate(int i){
		lz[i*2]+=lz[i];
		lz[i*2+1]+=lz[i];
		mn[i]+=lz[i];
		lz[i]=0;
	}
	void Add(int b,int e,int l,int r,int i,int v){
		if(e<=l||r<=b)
			return;
		if(b<=l&&r<=e){
			lz[i]+=v;
			return;
		}
		Propagate(i);
		Add(b,e,l,(l+r)/2,i*2,v);
		Add(b,e,(l+r)/2,r,i*2+1,v);
		mn[i]=min(NodeMin(i*2),NodeMin(i*2+1));
	}
	void Add(int b,int e,int v){
		Add(b,e,0,s,1,v);
	}
	int Get(int b,int e,int l,int r,int i){
		if(e<=l||r<=b)
			return inf;
		if(b<=l&&r<=e)
			return NodeMin(i);
		Propagate(i);
		return min(Get(b,e,l,(l+r)/2,i*2),Get(b,e,(l+r)/2,r,i*2+1));
	}
	int Get(int b,int e){
		return Get(b,e,0,s,1);
	}
} seg;

const int Nmax=334893;
struct Pos{
	int x,y;
} ps[Nmax];
int n,m,k;

struct Query{
	int y,b,e,v;
	bool operator<(const Query& rhs)const{
		return y<rhs.y;
	}
} qs[Nmax];


pii GetRange(int y){
	int b=abs(y);
	int e=(n-1)+(m-1)-abs(y-((m-1)-(n-1)))+1;
	return pii(b,e);
}

bool Solve(int s){
	REP(i,k){
		qs[i*2]=Query{ps[i].y-s,max(0,ps[i].x-s),min(n+m,ps[i].x+s+1),1};
		qs[i*2+1]=Query{ps[i].y+s+1,max(0,ps[i].x-s),min(n+m,ps[i].x+s+1),-1};
	}
	qs[k*2]=Query{inf,0,0,0};
	sort(qs,qs+2*k+1);
	//for even
	{
		auto modify=[](int& v){
			if(v&1)v++;
		};
		seg.Init(n+m);
		int lastY=-(n-1);
		modify(lastY);
		REP(i,2*k+1){
			Query q=qs[i];
			modify(q.y);
			modify(q.b);
			modify(q.e);
			if(lastY<q.y){
				pii u=GetRange(lastY),b=GetRange(q.y-1);
				if(lastY<=0&&0<=q.y-1)
					u.first=0;
				if(lastY<=(m-1)-(n-1)&&(m-1)-(n-1)<=q.y-1)
					u.second=(m-1)+(n-1)+1;
				modify(u.first);
				modify(u.second);
				modify(b.first);
				modify(b.second);
				if(seg.Get(min(u.first,b.first)/2,max(u.second,b.second)/2)==0)
					return true;
			}
			seg.Add(q.b/2,q.e/2,q.v);
			lastY=q.y;
		}
	}
	//for odd
	{
		auto modify=[](int& v){
			if(!(v&1))v++;
		};
		seg.Init(n+m);
		int lastY=-(n-1);
		modify(lastY);
		REP(i,2*k+1){
			Query q=qs[i];
			modify(q.y);
			modify(q.b);
			modify(q.e);
			if(lastY<q.y){
				pii u=GetRange(lastY),b=GetRange(q.y-1);
				if(lastY<=0&&0<=q.y-1)
					u.first=0;
				if(lastY<=(m-1)-(n-1)&&(m-1)-(n-1)<=q.y-1)
					u.second=(m-1)+(n-1)+1;
				modify(u.first);
				modify(u.second);
				modify(b.first);
				modify(b.second);
				if(seg.Get(min(u.first,b.first)/2,max(u.second,b.second)/2)==0)
					return true;
			}
			seg.Add(q.b/2,q.e/2,q.v);
			lastY=q.y;
		}
	}
	return false;
}

int main(){
	n=read(),m=read(),k=read();
	REP(i,k){
		int x=read(),y=read();
		ps[i]=Pos{x+y,y-x};
	}
	int l=-1,r=n+m;
	while(r-l>1){
		int mid=(r+l)/2;
		if(Solve(mid))
			l=mid;
		else
			r=mid;
	}
	cout<<r<<endl;
}
accuracy: 1
time_ms: 1340
memory_kb: 9196
final_rank: 1