明天要打 NOIO ,因为好久没写题了,所以随机了一条蓝题练练手。
明明是二维前缀和板子,但调了半天迷之 RE 死活过不去,貌似提交记录就我一个 60 的/kk
所以希望有神仙赐教,蒟蒻不胜感激/kel
#include<bits/stdc++.h>
#define up(l,r,i) for(int i=l,END##i=r;i<=END##i;++i)
#define dn(r,l,i) for(int i=r,END##i=l;i>=END##i;--i)
using namespace std;
typedef long long i64;
const int INF =1e9;
#define num(t1,t2,t3,t4) (S[t3][t4]-S[t1-1][t4]-S[t3][t2-1]+S[t1-1][t2-1])
const int MAXN=500+3,MAXM=5e4+3;
int S[MAXN][MAXN],A[MAXM],B[MAXM],p,r,c,n;
void clc(int l,int w,int *W){
up(1,l,i) up(1,w,j) S[i][j]=0; up(1,n,i) ++S[A[i]][B[i]];
up(1,l,i) up(1,w,j) S[i][j]+=S[i-1][j]+S[i][j-1]-S[i-1][j-1];
up(1,l,i) W[i]=INF; up(1,l,i) up(1,w,j){
int t=1; up(j,w,k){ //(t,j)--(i,k)
while(t<i&&num(t+1,j,i,k)>=p) ++t;
if(num(t,j,i,k)==p) W[i]=min(W[i],i-t+k-j+2);
}
}
up(2,l,i) W[i]=min(W[i],W[i-1]);
}
int qread(){
int w=1,c,ret;
while((c=getchar())> '9'||c< '0') w=(c=='-'?-1:1); ret=c-'0';
while((c=getchar())>='0'&&c<='9') ret=ret*10+c-'0';
return ret*w;
}
int W1[MAXN],W2[MAXN],ans=INF;
int main(){
r=qread(),c=qread(),n=qread(),p=qread();
up(1,n,i) A[i]=qread(),B[i]=qread(); clc(r,c,W1);
up(1,n,i) A[i]=r-A[i]+1; clc(r,c,W2);
up(1,r-1,i) ans=min(ans,W1[i]+W2[r-i]);
up(1,n,i) swap(A[i],B[i]); clc(c,r,W1);
up(1,n,i) A[i]=c-A[i]+1; clc(c,r,W2);
up(1,c-1,i) ans=min(ans,W1[i]+W2[c-i]);
if(ans>=INF) puts("NO"); else printf("%d\n",ans<<1);
return 0;
}