【NOIP2016提高A組五校聯考4】square
阿新 • • 發佈:2018-05-21
TP space net AS noip getch 分享 OS 什麽
題目
分析
首先,設\(f_{i,j}\)表示最大的以(i,j)為左下角的正方形的邊長。
轉移顯然,\(f_{i,j}=\max(f_{i-1,j},f_{i,j-1},f_{i-1,j-1})+1\)
接著,再設\(g_{i,j,k,l}\)表示在以\((k,l)\)為左上角,\((k+2^i-1,l+2^j-1)\)為右下角的矩陣中,最大的f。
二維rmq就不講了。
假設詢問矩陣(x,y,x1,y1),
二分答案ans(想想為什麽?)
用rmq看紅色區域中的最大f值是否合法。
註意:出題人將輸入調的太大了,要打讀入優化。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> #include <cmath> const int maxlongint=2147483647; const int mo=1000000007; const int N=1002; using namespace std; int f[N][N],n,m,T,g[11][11][N][N],a[N][N],logn,logm; int read(int &n) { char ch=' '; int q=0,w=1; for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar()); if(ch=='-') w=-1,ch=getchar(); for(;ch>='0' && ch<='9';ch=getchar()) q=q*10+ch-48;n=q*w; return n; } int min2(int x,int y) { if(x>y) x=y; return x; } int max2(int x,int y) { if(x<y) x=y; return x; } int min1(int x,int y,int z) { if(x>y) x=y; if(x>z) x=z; return x; } int max1(int x,int y,int z,int a) { if(x<y) x=y; if(x<z) x=z; if(x<a) x=a; return x; } int pref() { int i,j; for(i=1;i<=n;i++) for(j=1;j<=m;j++) if(a[i][j]) g[0][0][i][j]=f[i][j]=min1(f[i-1][j-1],f[i-1][j],f[i][j-1])+1; } int prermq() { int i,j,k,l; for(i=0;i<=logn;i++) { for(j=0;j<=logm;j++) { if(j+i!=0) { int p=1<<(i-1); int q=1<<(j-1); for(k=1;k<=n;k++) if(k+p<=n) { for(l=1;l<=m;l++) if(l+q<=m) { if(i!=0 && j!=0) g[i][j][k][l]=max1(g[i-1][j-1][k][l],g[i-1][j-1][k+p][l],g[i-1][j-1][k+p][l+q],g[i-1][j-1][k][l+q]); else if(i==0) g[i][j][k][l]=max2(g[i][j-1][k][l],g[i][j-1][k][l+q]); else if(j==0) g[i][j][k][l]=max2(g[i-1][j][k][l],g[i-1][j][k+p][l]); } else break; } else break; } } } } int rmq(int x,int y,int x1,int y1) { int p=log2(x1-x+1),q=log2(y1-y+1); return max1(g[p][q][x][y],g[p][q][x1-(1<<p)+1][y],g[p][q][x][y1-(1<<q)+1],g[p][q][x1-(1<<p)+1][y1-(1<<q)+1]); } int rf(int x,int y,int x1,int y1) { int lx=x1-x+1,ly=y1-y+1,l=1,r=min2(lx,ly); while(l<r-1) { int mid=(l+r)/2; if(rmq(x+mid-1,y+mid-1,x1,y1)>=mid) l=mid; else r=mid-1; } if(rmq(x+r-1,y+r-1,x1,y1)>=r) printf("%d\n",r); else if(rmq(x+l-1,y+l-1,x1,y1)>=l) printf("%d\n",l); else printf("0\n"); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { read(a[i][j]); f[i][j]=a[i][j]; } pref(); logn=log2(n); logm=log2(m); prermq(); scanf("%d",&T); int x1,x2,y1,y2; for(int i=1;i<=T;i++) { read(x1); read(y1); read(x2); read(y2); rf(x1,y1,x2,y2); } }
【NOIP2016提高A組五校聯考4】square