萌新求助二维前缀和
查看原帖
萌新求助二维前缀和
330759
囧仙楼主2021/3/26 19:59

明天要打 NOIO\mathcal{NOIO} ,因为好久没写题了,所以随机了一条蓝题练练手。

明明是二维前缀和板子,但调了半天迷之 RE\text{RE} 死活过不去,貌似提交记录就我一个 6060 的/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;
}
2021/3/26 19:59
加载中...