题意
给你一个 的只包含四种颜色的网格。
此询问,每次问一个矩阵中所包含的形如以下格式的 的最大面积
题解
如何确定包含某个点的最大纯色正方形?
只考虑以点 为右下角的颜色为 的最大正方形的边长,设其为 .
则有:
如何确定包含某个点的最大的 ?
考虑红色方块的右下角 ,则边长为 的 合法的充要条件为:
当存在这样的 满足上述条件时,记 .
如何确定某个矩阵内的最大 ?
先考虑如何判定边长为 的 是否存在.
因为所记录的 为红色方块的右下角,故可以确定 的选点范围为子矩阵
如果存在这样的 ,也就是子矩阵中存在 ,也就是子矩阵内 .
可以发现 的有单调性的,故可以通过二分找到最大的 .
考虑另外一种思路
在第二步时记满足条件式的最大的 为 .
那么在第三步时的判定条件将变为 子矩阵中 .
总结下来题目体质就是求矩阵和或矩阵最大值.
具体方法为:
预处理前缀和,差分,时间复杂度 ,空间复杂度 .
inline void Prepare(){
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
for(k=min(min(i,n-i),min(j,m-j));k>=1;--k){
S[k][i][j]=S[k][i-1][j]+S[k][i][j-1]-S[k][i-1][j-1];
if(L[0][i][j]>=k&&L[1][i][j+k]>=k&&L[2][i+k][j+k]>=k&&L[3][i+k][j]>=k){
for(int l=k;l>=1;--l)
S[l][i][j]=S[l][i-1][j]+S[l][i][j-1]-S[l][i-1][j-1]+1;
break;
}
}
}
inline bool Qry(int x1,int y1,int x2,int y2,int k){
return S[k][x2][y2]-S[k][x1-1][y2]-S[k][x2][y1-1]+S[k][x1-1][y1-1];
}
二维 表,时间复杂度 ,空间复杂度 .
inline void Prepare(){
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
for(k=min(min(i,n-i),min(j,m-j));k>=1;--k)
if(L[0][i][j]>=k&&L[1][i][j+k]>=k&&L[2][i+k][j+k]>=k&&L[3][i+k][j]>=k){
f[0][0][i][j]=k;break;
}
for(int k=0;k<=Log[n];++k)
fp(int l=0;l<=Log[m];++l)
if(k||l)
for(int i=1;i+(1<<k)-1<=n;++i)
for(int j=1;j+(1<<l)-1<=n;++j)
f[k][l][i][j]=l?max(f[k][l-1][i][j],f[k][l-1][i][j+(1<<(l-1))]):
max(f[k-1][l][i][j],f[k-1][l][i+(1<<(k-1))][j]);
}
inline bool Qry(int x1,int y1,int x2,int y2,int k){
int Lx=Log[x2-x1+1],Ly=Log[y2-y1+1];
return k<=max(max(f[Lx][Ly][x1][y1],f[Lx][Ly][x2-(1<<Lx)+1][y2-(1<<Ly)+1]),
max(f[Lx][Ly][x2-(1<<Lx)+1][y1],f[Lx][Ly][x1][y2-(1<<Ly)+1]));
}
注意:参照点不止右下角一种选法,参照点选取的不同方案只影响子矩阵的范围和判定合法所选取的 .